Skip to content

Commit 21d340e

Browse files
committed
Added relative cursor move methods
1 parent 7f2b1b4 commit 21d340e

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

ext/io/console/console.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,27 @@ console_cursor_pos(VALUE io)
799799
return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.X), UINT2NUM(ws.dwCursorPosition.Y));
800800
}
801801

802+
static VALUE
803+
console_move(VALUE io, int x, int y)
804+
{
805+
rb_io_t *fptr;
806+
HANDLE h;
807+
rb_console_size_t ws;
808+
COORD *pos = &ws.dwCursorPosition;
809+
810+
GetOpenFile(io, fptr);
811+
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
812+
if (!GetConsoleScreenBufferInfo(h, &ws)) {
813+
rb_syserr_fail(LAST_ERROR, 0);
814+
}
815+
pos->X += x;
816+
pos->Y += y;
817+
if (!SetConsoleCursorPosition(h, *pos)) {
818+
rb_syserr_fail(LAST_ERROR, 0);
819+
}
820+
return io;
821+
}
822+
802823
#include "win32_vk.inc"
803824

804825
static VALUE
@@ -889,6 +910,19 @@ console_goto(VALUE io, VALUE x, VALUE y)
889910
rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y), NUM2UINT(x)));
890911
return io;
891912
}
913+
914+
static VALUE
915+
console_move(VALUE io, int x, int y)
916+
{
917+
if (x || y) {
918+
VALUE s = rb_str_new_cstr("");
919+
if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B');
920+
if (x) rb_str_catf(s, "\x1b[%d%c", x < 0 ? -x : x, x < 0 ? 'D' : 'C');
921+
rb_io_write(io, s);
922+
rb_io_flush(io);
923+
}
924+
return io;
925+
}
892926
# define console_key_pressed_p rb_f_notimplement
893927
#endif
894928

@@ -900,6 +934,38 @@ console_cursor_set(VALUE io, VALUE cpos)
900934
return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1));
901935
}
902936

937+
static VALUE
938+
console_cursor_up(VALUE io, VALUE val)
939+
{
940+
return console_move(io, 0, -NUM2INT(val));
941+
}
942+
943+
static VALUE
944+
console_cursor_down(VALUE io, VALUE val)
945+
{
946+
return console_move(io, 0, +NUM2INT(val));
947+
}
948+
949+
static VALUE
950+
console_cursor_left(VALUE io, VALUE val)
951+
{
952+
return console_move(io, -NUM2INT(val), 0);
953+
}
954+
955+
static VALUE
956+
console_cursor_right(VALUE io, VALUE val)
957+
{
958+
return console_move(io, +NUM2INT(val), 0);
959+
}
960+
961+
static VALUE
962+
console_clear_screen(VALUE io)
963+
{
964+
console_erase_screen(io, INT2FIX(2));
965+
console_goto(io, INT2FIX(1), INT2FIX(1));
966+
return io;
967+
}
968+
903969
/*
904970
* call-seq:
905971
* IO.console -> #<File:/dev/tty>
@@ -1124,6 +1190,10 @@ InitVM_console(void)
11241190
rb_define_method(rb_cIO, "goto", console_goto, 2);
11251191
rb_define_method(rb_cIO, "cursor", console_cursor_pos, 0);
11261192
rb_define_method(rb_cIO, "cursor=", console_cursor_set, 1);
1193+
rb_define_method(rb_cIO, "cursor_up", console_cursor_up, 1);
1194+
rb_define_method(rb_cIO, "cursor_down", console_cursor_down, 1);
1195+
rb_define_method(rb_cIO, "cursor_left", console_cursor_left, 1);
1196+
rb_define_method(rb_cIO, "cursor_right", console_cursor_right, 1);
11271197
rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1);
11281198
#if ENABLE_IO_GETPASS
11291199
rb_define_method(rb_cIO, "getpass", console_getpass, -1);

0 commit comments

Comments
 (0)