[ruby/io-console] Intersperse Win32 and termios implementations

So that the both sources appear in RDoc generated HTMLs.

https://github.com/ruby/io-console/commit/beec164a47
This commit is contained in:
Nobuyoshi Nakada 2023-10-22 11:52:15 +09:00 committed by git
parent 0f02a86a3d
commit 7578bc35f9

View File

@ -1010,67 +1010,6 @@ mode_in_range(VALUE val, int high, const char *modename)
} }
#if defined _WIN32 #if defined _WIN32
static VALUE
console_goto(VALUE io, VALUE y, VALUE x)
{
COORD pos;
int fd = GetWriteFD(io);
pos.X = NUM2UINT(x);
pos.Y = NUM2UINT(y);
if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
rb_syserr_fail(LAST_ERROR, 0);
}
return io;
}
static VALUE
console_cursor_pos(VALUE io)
{
rb_console_size_t ws;
int fd = GetWriteFD(io);
if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X));
}
static VALUE
console_move(VALUE io, int y, int x)
{
HANDLE h;
rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
pos->X += x;
pos->Y += y;
if (!SetConsoleCursorPosition(h, *pos)) {
rb_syserr_fail(LAST_ERROR, 0);
}
return io;
}
static VALUE
console_goto_column(VALUE io, VALUE val)
{
HANDLE h;
rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
pos->X = NUM2INT(val);
if (!SetConsoleCursorPosition(h, *pos)) {
rb_syserr_fail(LAST_ERROR, 0);
}
return io;
}
static void static void
constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos) constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos)
{ {
@ -1080,74 +1019,6 @@ constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos)
FillConsoleOutputCharacterW(handle, L' ', len, pos, &written); FillConsoleOutputCharacterW(handle, L' ', len, pos, &written);
} }
static VALUE
console_erase_line(VALUE io, VALUE val)
{
HANDLE h;
rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
DWORD w;
int mode = mode_in_range(val, 2, "line erase");
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
w = winsize_col(&ws);
switch (mode) {
case 0: /* after cursor */
w -= pos->X;
break;
case 1: /* before *and* cursor */
w = pos->X + 1;
pos->X = 0;
break;
case 2: /* entire line */
pos->X = 0;
break;
}
constat_clear(h, ws.wAttributes, w, *pos);
return io;
}
static VALUE
console_erase_screen(VALUE io, VALUE val)
{
HANDLE h;
rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
DWORD w;
int mode = mode_in_range(val, 3, "screen erase");
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
w = winsize_col(&ws);
switch (mode) {
case 0: /* erase after cursor */
w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X);
break;
case 1: /* erase before *and* cursor */
w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1);
pos->X = 0;
pos->Y = ws.srWindow.Top;
break;
case 2: /* erase entire screen */
w = (w * winsize_row(&ws));
pos->X = 0;
pos->Y = ws.srWindow.Top;
break;
case 3: /* erase entire screen */
w = (w * ws.dwSize.Y);
pos->X = 0;
pos->Y = 0;
break;
}
constat_clear(h, ws.wAttributes, w, *pos);
return io;
}
static VALUE static VALUE
console_scroll(VALUE io, int line) console_scroll(VALUE io, int line)
{ {
@ -1267,9 +1138,31 @@ console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qa
return ret; return ret;
} }
static VALUE
console_scroll(VALUE io, int line)
{
if (line) {
VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line,
line < 0 ? 'T' : 'S');
rb_io_write(io, s);
}
return io;
}
# define console_key_pressed_p rb_f_notimplement
#endif
static VALUE static VALUE
console_cursor_pos(VALUE io) console_cursor_pos(VALUE io)
{ {
#ifdef _WIN32
rb_console_size_t ws;
int fd = GetWriteFD(io);
if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X));
#else
static const struct query_args query = {"\033[6n", 0}; static const struct query_args query = {"\033[6n", 0};
VALUE resp = console_vt_response(0, 0, io, &query); VALUE resp = console_vt_response(0, 0, io, &query);
VALUE row, column, term; VALUE row, column, term;
@ -1286,18 +1179,44 @@ console_cursor_pos(VALUE io)
RARRAY_ASET(resp, 0, INT2NUM(r)); RARRAY_ASET(resp, 0, INT2NUM(r));
RARRAY_ASET(resp, 1, INT2NUM(c)); RARRAY_ASET(resp, 1, INT2NUM(c));
return resp; return resp;
#endif
} }
static VALUE static VALUE
console_goto(VALUE io, VALUE y, VALUE x) console_goto(VALUE io, VALUE y, VALUE x)
{ {
#ifdef _WIN32
COORD pos;
int fd = GetWriteFD(io);
pos.X = NUM2UINT(x);
pos.Y = NUM2UINT(y);
if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
rb_syserr_fail(LAST_ERROR, 0);
}
#else
rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1)); rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1));
#endif
return io; return io;
} }
static VALUE static VALUE
console_move(VALUE io, int y, int x) console_move(VALUE io, int y, int x)
{ {
#ifdef _WIN32
HANDLE h;
rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
pos->X += x;
pos->Y += y;
if (!SetConsoleCursorPosition(h, *pos)) {
rb_syserr_fail(LAST_ERROR, 0);
}
#else
if (x || y) { if (x || y) {
VALUE s = rb_str_new_cstr(""); VALUE s = rb_str_new_cstr("");
if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B'); if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B');
@ -1305,13 +1224,29 @@ console_move(VALUE io, int y, int x)
rb_io_write(io, s); rb_io_write(io, s);
rb_io_flush(io); rb_io_flush(io);
} }
#endif
return io; return io;
} }
static VALUE static VALUE
console_goto_column(VALUE io, VALUE val) console_goto_column(VALUE io, VALUE val)
{ {
#ifdef _WIN32
HANDLE h;
rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
pos->X = NUM2INT(val);
if (!SetConsoleCursorPosition(h, *pos)) {
rb_syserr_fail(LAST_ERROR, 0);
}
#else
rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1)); rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1));
#endif
return io; return io;
} }
@ -1319,7 +1254,34 @@ static VALUE
console_erase_line(VALUE io, VALUE val) console_erase_line(VALUE io, VALUE val)
{ {
int mode = mode_in_range(val, 2, "line erase"); int mode = mode_in_range(val, 2, "line erase");
#ifdef _WIN32
HANDLE h;
rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
DWORD w;
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
w = winsize_col(&ws);
switch (mode) {
case 0: /* after cursor */
w -= pos->X;
break;
case 1: /* before *and* cursor */
w = pos->X + 1;
pos->X = 0;
break;
case 2: /* entire line */
pos->X = 0;
break;
}
constat_clear(h, ws.wAttributes, w, *pos);
return io;
#else
rb_io_write(io, rb_sprintf("\x1b[%dK", mode)); rb_io_write(io, rb_sprintf("\x1b[%dK", mode));
#endif
return io; return io;
} }
@ -1327,22 +1289,43 @@ static VALUE
console_erase_screen(VALUE io, VALUE val) console_erase_screen(VALUE io, VALUE val)
{ {
int mode = mode_in_range(val, 3, "screen erase"); int mode = mode_in_range(val, 3, "screen erase");
rb_io_write(io, rb_sprintf("\x1b[%dJ", mode)); #ifdef _WIN32
return io; HANDLE h;
} rb_console_size_t ws;
COORD *pos = &ws.dwCursorPosition;
DWORD w;
static VALUE h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
console_scroll(VALUE io, int line) if (!GetConsoleScreenBufferInfo(h, &ws)) {
{ rb_syserr_fail(LAST_ERROR, 0);
if (line) {
VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line,
line < 0 ? 'T' : 'S');
rb_io_write(io, s);
} }
w = winsize_col(&ws);
switch (mode) {
case 0: /* erase after cursor */
w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X);
break;
case 1: /* erase before *and* cursor */
w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1);
pos->X = 0;
pos->Y = ws.srWindow.Top;
break;
case 2: /* erase entire screen */
w = (w * winsize_row(&ws));
pos->X = 0;
pos->Y = ws.srWindow.Top;
break;
case 3: /* erase entire screen */
w = (w * ws.dwSize.Y);
pos->X = 0;
pos->Y = 0;
break;
}
constat_clear(h, ws.wAttributes, w, *pos);
#else
rb_io_write(io, rb_sprintf("\x1b[%dJ", mode));
#endif
return io; return io;
} }
# define console_key_pressed_p rb_f_notimplement
#endif
static VALUE static VALUE
console_cursor_set(VALUE io, VALUE cpos) console_cursor_set(VALUE io, VALUE cpos)