ruby-changes:57695
From: Nobuyoshi <ko1@a...>
Date: Tue, 10 Sep 2019 08:18:26 +0900 (JST)
Subject: [ruby-changes:57695] e8be056af9 (master): [ruby/io-console] Added relative cursor move methods
https://git.ruby-lang.org/ruby.git/commit/?id=e8be056af9 From e8be056af92b2f13162567c057322a2c16797b79 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Mon, 9 Sep 2019 23:51:44 +0900 Subject: [ruby/io-console] Added relative cursor move methods https://github.com/ruby/io-console/commit/21d340e4a2 diff --git a/ext/io/console/console.c b/ext/io/console/console.c index db40c1b..a99846c 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -799,6 +799,27 @@ console_cursor_pos(VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L799 return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.X), UINT2NUM(ws.dwCursorPosition.Y)); } +static VALUE +console_move(VALUE io, int x, int y) +{ + rb_io_t *fptr; + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + GetOpenFile(io, fptr); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); + 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; +} + #include "win32_vk.inc" static VALUE @@ -889,6 +910,19 @@ console_goto(VALUE io, VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L910 rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y), NUM2UINT(x))); return io; } + +static VALUE +console_move(VALUE io, int x, int y) +{ + if (x || y) { + VALUE s = rb_str_new_cstr(""); + if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B'); + if (x) rb_str_catf(s, "\x1b[%d%c", x < 0 ? -x : x, x < 0 ? 'D' : 'C'); + rb_io_write(io, s); + rb_io_flush(io); + } + return io; +} # define console_key_pressed_p rb_f_notimplement #endif @@ -900,6 +934,38 @@ console_cursor_set(VALUE io, VALUE cpos) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L934 return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1)); } +static VALUE +console_cursor_up(VALUE io, VALUE val) +{ + return console_move(io, 0, -NUM2INT(val)); +} + +static VALUE +console_cursor_down(VALUE io, VALUE val) +{ + return console_move(io, 0, +NUM2INT(val)); +} + +static VALUE +console_cursor_left(VALUE io, VALUE val) +{ + return console_move(io, -NUM2INT(val), 0); +} + +static VALUE +console_cursor_right(VALUE io, VALUE val) +{ + return console_move(io, +NUM2INT(val), 0); +} + +static VALUE +console_clear_screen(VALUE io) +{ + console_erase_screen(io, INT2FIX(2)); + console_goto(io, INT2FIX(1), INT2FIX(1)); + return io; +} + /* * call-seq: * IO.console -> #<File:/dev/tty> @@ -1124,6 +1190,10 @@ InitVM_console(void) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L1190 rb_define_method(rb_cIO, "goto", console_goto, 2); rb_define_method(rb_cIO, "cursor", console_cursor_pos, 0); rb_define_method(rb_cIO, "cursor=", console_cursor_set, 1); + rb_define_method(rb_cIO, "cursor_up", console_cursor_up, 1); + rb_define_method(rb_cIO, "cursor_down", console_cursor_down, 1); + rb_define_method(rb_cIO, "cursor_left", console_cursor_left, 1); + rb_define_method(rb_cIO, "cursor_right", console_cursor_right, 1); rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1); #if ENABLE_IO_GETPASS rb_define_method(rb_cIO, "getpass", console_getpass, -1); -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/