From 10e3267c31c4c976d79e00bca484094f1a87dc65 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 24 Sep 2019 15:53:58 +0900 Subject: [PATCH] [ruby/io-console] Made cursor position 0-origin https://github.com/ruby/io-console/commit/9377e37295 --- ext/io/console/console.c | 9 +++++++-- test/io/console/test_io_console.rb | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ext/io/console/console.c b/ext/io/console/console.c index 1d6ebc874d..2604715605 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -1109,6 +1109,7 @@ console_cursor_pos(VALUE io) VALUE query = rb_str_new_cstr("\e[6n"); VALUE resp = console_vt_response(1, &query, io); VALUE row, column, term; + unsigned int r, c; if (!RB_TYPE_P(resp, T_ARRAY) || RARRAY_LEN(resp) != 3) return Qnil; term = RARRAY_AREF(resp, 2); if (!RB_TYPE_P(term, T_STRING) || RSTRING_LEN(term) != 1) return Qnil; @@ -1116,13 +1117,17 @@ console_cursor_pos(VALUE io) row = RARRAY_AREF(resp, 0); column = RARRAY_AREF(resp, 1); rb_ary_resize(resp, 2); + r = NUM2UINT(row) - 1; + c = NUM2UINT(column) - 1; + RARRAY_ASET(resp, 0, INT2NUM(r)); + RARRAY_ASET(resp, 1, INT2NUM(c)); return resp; } static VALUE console_goto(VALUE io, VALUE y, VALUE x) { - rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y), NUM2UINT(x))); + rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1)); return io; } @@ -1223,7 +1228,7 @@ static VALUE console_clear_screen(VALUE io) { console_erase_screen(io, INT2FIX(2)); - console_goto(io, INT2FIX(1), INT2FIX(1)); + console_goto(io, INT2FIX(0), INT2FIX(0)); return io; } diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb index db3814d51c..c81d80fa08 100644 --- a/test/io/console/test_io_console.rb +++ b/test/io/console/test_io_console.rb @@ -281,6 +281,26 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do set_winsize_teardown end + def test_cursor_position + run_pty("#{<<~"begin;"}\n#{<<~'end;'}") do |r, w, _| + begin; + con = IO.console + p con.cursor + con.cursor_down(3); con.puts + con.cursor_right(4); con.puts + con.cursor_left(2); con.puts + con.cursor_up(1); con.puts + end; + assert_equal("\e[6n", r.readpartial(5)) + w.print("\e[12;34R"); w.flush + assert_equal([11, 33], eval(r.gets)) + assert_equal("\e[3B", r.gets.chomp) + assert_equal("\e[4C", r.gets.chomp) + assert_equal("\e[2D", r.gets.chomp) + assert_equal("\e[1A", r.gets.chomp) + end + end + unless IO.console def test_close assert_equal(["true"], run_pty("IO.console.close; p IO.console.fileno >= 0"))