8000 tty, feat: support cursorTo and moveCursor. · fibjs/fibjs@3e25a8f · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit 3e25a8f

Browse files
committed
tty, feat: support cursorTo and moveCursor.
1 parent 65d4f77 commit 3e25a8f

File tree

5 files changed

+128
-2
lines changed

5 files changed

+128
-2
lines changed

fibjs/include/TTYStream.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @email richardo2016
44
* @create date 2021-04-10 02:16:35
55
* @modify date 2021-04-10 02:16:35
6-
*
6+
*
77
* @desc tty about stream implementation
88
*/
99

@@ -81,6 +81,8 @@ class TTYOutputStream : public UVStream_tmpl<TTYOutputStream_base> {
8181
virtual result_t get_rows(int32_t& retVal);
8282
virtual result_t clearLine(int32_t dir);
8383
virtual result_t clearScreenDown();
84+
virtual result_t cursorTo(int32_t x, int32_t y, AsyncEvent* ac);
85+
virtual result_t moveCursor(int32_t dx, int32_t dy, AsyncEvent* ac);
8486
virtual result_t getWindowSize(obj_ptr<NArray>& retVal);
8587

8688
public:

fibjs/include/ifs/TTYOutputStream.h

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class TTYOutputStream_base : public Stream_base {
2828
virtual result_t get_rows(int32_t& retVal) = 0;
2929
virtual result_t clearLine(int32_t dir) = 0;
3030
virtual result_t clearScreenDown() = 0;
31+
virtual result_t cursorTo(int32_t x, int32_t y, AsyncEvent* ac) = 0;
32+
virtual result_t moveCursor(int32_t dx, int32_t dy, AsyncEvent* ac) = 0;
3133
virtual result_t getWindowSize(obj_ptr<NArray>& retVal) = 0;
3234

3335
public:
@@ -45,7 +47,13 @@ class TTYOutputStream_base : public Stream_base {
4547
static void s_get_rows(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
4648
static void s_clearLine(const v8::FunctionCallbackInfo<v8::Value>& args);
4749
static void s_clearScreenDown(const v8::FunctionCallbackInfo<v8::Value>& args);
50+
static void s_cursorTo(const v8::FunctionCallbackInfo<v8::Value>& args);
51+
static void s_moveCursor(const v8::FunctionCallbackInfo<v8::Value>& args);
4852
static void s_getWindowSize(const v8::FunctionCallbackInfo<v8::Value>& args);
53+
54+
public:
55+
ASYNC_MEMBER2(TTYOutputStream_base, cursorTo, int32_t, int32_t);
56+
ASYNC_MEMBER2(TTYOutputStream_base, moveCursor, int32_t, int32_t);
4957
};
5058
}
5159

@@ -55,6 +63,10 @@ inline ClassInfo& TTYOutputStream_base::class_info()
5563
static ClassData::ClassMethod s_method[] = {
5664
{ "clearLine", s_clearLine, false, false },
5765
{ "clearScreenDown", s_clearScreenDown, false, false },
66+
{ "cursorTo", s_cursorTo, false, true },
67+
{ "cursorToSync", s_cursorTo, false, false },
68+
{ "moveCursor", s_moveCursor, false, true },
69+
{ "moveCursorSync", s_moveCursor, false, false },
5870
{ "getWindowSize", s_getWindowSize, false, false }
5971
};
6072

@@ -68,7 +80,7 @@ inline ClassInfo& TTYOutputStream_base::class_info()
6880
"TTYOutputStream", false, s__new, NULL,
6981
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
7082
&Stream_base::class_info(),
71-
false
83+
true
7284
};
7385

7486
static ClassInfo s_ci(s_cd);
@@ -137,6 +149,42 @@ inline void TTYOutputStream_base::s_clearScreenDown(const v8::FunctionCallbackIn
137149
METHOD_VOID();
138150
}
139151

152+
inline void TTYOutputStream_base::s_cursorTo(const v8::FunctionCallbackInfo<v8::Value>& args)
153+
{
154+
ASYNC_METHOD_INSTANCE(TTYOutputStream_base);
155+
METHOD_ENTER();
156+
157+
ASYNC_METHOD_OVER(2, 1);
158+
159+
ARG(int32_t, 0);
160+
OPT_ARG(int32_t, 1, -1);
161+
162+
if (!cb.IsEmpty())
163+
hr = pInst->acb_cursorTo(v0, v1, cb, args);
164+
else
165+
hr = pInst->ac_cursorTo(v0, v1);
166+
167+
METHOD_VOID();
168+
}
169+
170+
inline void TTYOutputStream_base::s_moveCursor(const v8::FunctionCallbackInfo<v8::Value>& args)
171+
{
172+
ASYNC_METHOD_INSTANCE(TTYOutputStream_base);
173+
METHOD_ENTER();
174+
175+
ASYNC_METHOD_OVER(2, 2);
176+
177+
ARG(int32_t, 0);
178+
ARG(int32_t, 1);
179+
180+
if (!cb.IsEmpty())
181+
hr = pInst->acb_moveCursor(v0, v1, cb, args);
182+
else
183+
hr = pInst->ac_moveCursor(v0, v1);
184+
185+
METHOD_VOID();
186+
}
187+
140188
inline void TTYOutputStream_base::s_getWindowSize(const v8::FunctionCallbackInfo<v8::Value>& args)
141189
{
142190
obj_ptr<NArray> vr;

fibjs/src/console/tty.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "ifs/tty.h"
33
#include "AsyncUV.h"
44
#include "TTYStream.h"
5+
#include "console.h"
56

67
#ifdef _WIN32
78
#include <io.h>
@@ -89,6 +90,49 @@ result_t TTYOutputStream::clearScreenDown()
8990
return 0;
9091
}
9192

93+
result_t TTYOutputStream::cursorTo(int32_t x, int32_t y, AsyncEvent* ac)
94+
{
95+
if (x < 0)
96+
return CHECK_ERROR(CALL_E_INVALIDARG);
97+
98+
if (ac->isSync())
99+
return CHECK_ERROR(CALL_E_NOSYNC);
100+
101+
char numStr[64];
102+
103+
if (y >= 0)
104+
snprintf(numStr, sizeof(numStr), "\x1b[%d;%dH", y + 1, x + 1);
105+
else
106+
snprintf(numStr, sizeof(numStr), "\x1b[%dG", x + 1);
107+
108+
asyncLog(console_base::C_PRINT, numStr);
109+
110+
return 0;
111+
}
112+
113+
result_t TTYOutputStream::moveCursor(int32_t dx, int32_t dy, AsyncEvent* ac)
114+
{
115+
if (ac->isSync())
116+
return CHECK_ERROR(CALL_E_NOSYNC);
117+
118+
char numStr[64];
119+
char* data = numStr;
120+
121+
if (dx < 0)
122+
data += snprintf(data, sizeof(numStr) / 2, "\x1b[%dD", -dx);
123+
else if (dx > 0)
124+
data += snprintf(data, sizeof(numStr) / 2, "\x1b[%dC", dx);
125+
126+
if (dy < 0)
127+
data += snprintf(data, sizeof(numStr) / 2, "\x1b[%dA", -dy);
128+
else if (dy > 0)
129+
data += snprintf(data, sizeof(numStr) / 2, "\x1b[%dB", dy);
130+
131+
asyncLog(console_base::C_PRINT, numStr);
132+
133+
return 0;
134+
}
135+
92136
result_t TTYOutputStream::getWindowSize(obj_ptr<NArray>& retVal)
93137
{
94138
int32_t width, height;

idl/zh-cn/TTYOutputStream.idl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ interface TTYOutputStream : Stream
3636
*/
3737
clearScreenDown();
3838

39+
/*! @brief 将光标移动到指定位置
40+
@param x 指定的列数
41+
@param y 指定的行数,缺省为 -1,表示不改变行数
42+
*/
43+
cursorTo(Integer x, Integer y = -1) async;
44+
45+
/*! @brief 将光标移动指定的偏移量
46+
@param dx 指定的列偏移量
47+
@param dy 指定的行偏移量
48+
*/
49+
moveCursor(Integer dx, Integer dy) async;
50+
3951
/*! @brief 返回此 TTYOutputStream 对应的终端的尺寸
4052
@return 返回数组 [numColumns, numRows],其中 numColumns 和 numRows 表示相应终端中的列数和行数
4153
*/

npm/types/dts/interface/TTYOutputStream.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,26 @@ declare class Class_TTYOutputStream extends Class_Stream {
4949
*/
5050
clearScreenDown(): void;
5151

52+
/**
53+
* @description 将光标移动到指定位置
54+
* @param x 指定的列数
55+
* @param y 指定的行数,缺省为 -1,表示不改变行数
56+
*
57+
*/
58+
cursorTo(x: number, y?: number): void;
59+
60+
cursorTo(x: number, y?: number, callback?: (err: Error | undefined | null)=>any): void;
61+
62+
/**
63+
* @description 将光标移动指定的偏移量
64+
* @param dx 指定的列偏移量
65+
* @param dy 指定的行偏移量
66+
*
67+
*/
68+
moveCursor(dx: number, dy: number): void;
69+
70+
moveCursor(dx: number, dy: number, callback: (err: Error | undefined | null)=>any): void;
71+
5272
/**
5373
* @description 返回此 TTYOutputStream 对应的终端的尺寸
5474
* @return 返回数组 [numColumns, numRows],其中 numColumns 和 numRows 表示相应终端中的列数和行数

0 commit comments

Comments
 (0)
0