From 63dbeeecf42be757dd21a0d8fe1ff64a5f89b8f7 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 16 Dec 2023 15:30:02 +0900 Subject: [PATCH 1/3] Extract CSI sequence --- ext/io/console/console.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ext/io/console/console.c b/ext/io/console/console.c index 78eb11a..bc4be99 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -75,6 +75,8 @@ getattr(int fd, conmode *t) #define SET_LAST_ERROR (0) #endif +#define CSI "\x1b\x5b" + static ID id_getc, id_console, id_close; static ID id_gets, id_flush, id_chomp_bang; @@ -1142,7 +1144,7 @@ static VALUE console_scroll(VALUE io, int line) { if (line) { - VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line, + VALUE s = rb_sprintf(CSI "%d%c", line < 0 ? -line : line, line < 0 ? 'T' : 'S'); rb_io_write(io, s); } @@ -1204,7 +1206,7 @@ console_goto(VALUE io, VALUE y, VALUE x) 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(CSI "%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1)); #endif return io; } @@ -1229,8 +1231,8 @@ console_move(VALUE io, int y, int x) #else 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'); + if (y) rb_str_catf(s, CSI "%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B'); + if (x) rb_str_catf(s, CSI "%d%c", x < 0 ? -x : x, x < 0 ? 'D' : 'C'); rb_io_write(io, s); rb_io_flush(io); } @@ -1255,7 +1257,7 @@ console_goto_column(VALUE io, VALUE val) rb_syserr_fail(LAST_ERROR, 0); } #else - rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1)); + rb_io_write(io, rb_sprintf(CSI "%dG", NUM2UINT(val)+1)); #endif return io; } @@ -1290,7 +1292,7 @@ console_erase_line(VALUE io, VALUE val) 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(CSI "%dK", mode)); #endif return io; } @@ -1332,7 +1334,7 @@ console_erase_screen(VALUE io, VALUE val) } constat_clear(h, ws.wAttributes, w, *pos); #else - rb_io_write(io, rb_sprintf("\x1b[%dJ", mode)); + rb_io_write(io, rb_sprintf(CSI "%dJ", mode)); #endif return io; } From 43460589eaaf3159a1c1efd61990f4afc1797da5 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 16 Dec 2023 15:50:15 +0900 Subject: [PATCH 2/3] Add RDoc coverage task --- .gitignore | 1 + Rakefile | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/.gitignore b/.gitignore index 2340c41..630ca93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /coverage/ +/doc/ /html/ /pkg/ /tmp/ diff --git a/Rakefile b/Rakefile index 96ce2f1..13f1169 100644 --- a/Rakefile +++ b/Rakefile @@ -42,3 +42,13 @@ task :default => :test task "build" => "build:java" task "build:java" => "date_epoch" + +task "coverage" do + cov = [] + e = IO.popen([FileUtils::RUBY, "-S", "rdoc", "-C"], &:read) + e.scan(/^ *# in file (?.*)\n *(?.*)|^ *(?.*\S) *# in file (?.*)/) do + cov << "%s: %s\n" % $~.values_at(:loc, :code) + end + cov.sort! + puts cov +end From 44dce34569be13c9d050e459c5831eb955a0827e Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 16 Dec 2023 15:55:45 +0900 Subject: [PATCH 3/3] [DOC] Add missing documents --- .document | 1 + docs/io.rb | 4 ++ ext/io/console/console.c | 138 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 docs/io.rb diff --git a/.document b/.document index 4a1ddfe..e748855 100644 --- a/.document +++ b/.document @@ -1,4 +1,5 @@ LICENSE.txt README.md +docs/ ext/ lib/io/console/size.rb diff --git a/docs/io.rb b/docs/io.rb new file mode 100644 index 0000000..c13ca64 --- /dev/null +++ b/docs/io.rb @@ -0,0 +1,4 @@ +# :stopdoc: +class IO +end +# :startdoc: diff --git a/ext/io/console/console.c b/ext/io/console/console.c index bc4be99..6fd8677 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -898,6 +898,16 @@ console_set_winsize(VALUE io, VALUE size) #endif #ifdef _WIN32 +/* + * call-seq: + * io.check_winsize_changed { ... } -> io + * + * Yields while console input events are queued. + * + * This method is Windows only. + * + * You must require 'io/console' to use this method. + */ static VALUE console_check_winsize_changed(VALUE io) { @@ -984,6 +994,14 @@ console_ioflush(VALUE io) return io; } +/* + * call-seq: + * io.beep + * + * Beeps on the output console. + * + * You must require 'io/console' to use this method. + */ static VALUE console_beep(VALUE io) { @@ -1051,6 +1069,17 @@ console_scroll(VALUE io, int line) #include "win32_vk.inc" +/* + * call-seq: + * io.pressed?(key) -> bool + * + * Returns +true+ if +key+ is pressed. +key+ may be a virtual key + * code or its name (String or Symbol) with out "VK_" prefix. + * + * This method is Windows only. + * + * You must require 'io/console' to use this method. + */ static VALUE console_key_pressed_p(VALUE io, VALUE k) { @@ -1194,6 +1223,14 @@ console_cursor_pos(VALUE io) #endif } +/* + * call-seq: + * io.goto(line, column) -> io + * + * Set the cursor position at +line+ and +column+. + * + * You must require 'io/console' to use this method. + */ static VALUE console_goto(VALUE io, VALUE y, VALUE x) { @@ -1240,6 +1277,15 @@ console_move(VALUE io, int y, int x) return io; } +/* + * call-seq: + * io.goto_column(column) -> io + * + * Set the cursor position at +column+ in the same line of the current + * position. + * + * You must require 'io/console' to use this method. + */ static VALUE console_goto_column(VALUE io, VALUE val) { @@ -1262,6 +1308,18 @@ console_goto_column(VALUE io, VALUE val) return io; } +/* + * call-seq: + * io.erase_line(mode) -> io + * + * Erases the line at the cursor corresponding to +mode+. + * +mode+ may be either: + * 0: after cursor + * 1: before and cursor + * 2: entire line + * + * You must require 'io/console' to use this method. + */ static VALUE console_erase_line(VALUE io, VALUE val) { @@ -1297,6 +1355,18 @@ console_erase_line(VALUE io, VALUE val) return io; } +/* + * call-seq: + * io.erase_screen(mode) -> io + * + * Erases the screen at the cursor corresponding to +mode+. + * +mode+ may be either: + * 0: after cursor + * 1: before and cursor + * 2: entire screen + * + * You must require 'io/console' to use this method. + */ static VALUE console_erase_screen(VALUE io, VALUE val) { @@ -1339,6 +1409,16 @@ console_erase_screen(VALUE io, VALUE val) return io; } +/* + * call-seq: + * io.cursor = [line, column] -> io + * + * Same as io.goto(line, column) + * + * See IO#goto. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_set(VALUE io, VALUE cpos) { @@ -1347,42 +1427,98 @@ console_cursor_set(VALUE io, VALUE cpos) return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1)); } +/* + * call-seq: + * io.cursor_up(n) -> io + * + * Moves the cursor up +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_up(VALUE io, VALUE val) { return console_move(io, -NUM2INT(val), 0); } +/* + * call-seq: + * io.cursor_down(n) -> io + * + * Moves the cursor down +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_down(VALUE io, VALUE val) { return console_move(io, +NUM2INT(val), 0); } +/* + * call-seq: + * io.cursor_left(n) -> io + * + * Moves the cursor left +n+ columns. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_left(VALUE io, VALUE val) { return console_move(io, 0, -NUM2INT(val)); } +/* + * call-seq: + * io.cursor_right(n) -> io + * + * Moves the cursor right +n+ columns. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_right(VALUE io, VALUE val) { return console_move(io, 0, +NUM2INT(val)); } +/* + * call-seq: + * io.scroll_forward(n) -> io + * + * Scrolls the entire scrolls forward +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_scroll_forward(VALUE io, VALUE val) { return console_scroll(io, +NUM2INT(val)); } +/* + * call-seq: + * io.scroll_backward(n) -> io + * + * Scrolls the entire scrolls backward +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_scroll_backward(VALUE io, VALUE val) { return console_scroll(io, -NUM2INT(val)); } +/* + * call-seq: + * io.clear_screen -> io + * + * Clears the entire screen and moves the cursor top-left corner. + * + * You must require 'io/console' to use this method. + */ static VALUE console_clear_screen(VALUE io) { @@ -1677,7 +1813,9 @@ InitVM_console(void) rb_define_method(rb_cIO, "getpass", console_getpass, -1); rb_define_singleton_method(rb_cIO, "console", console_dev, -1); { + /* :stopdoc: */ VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable"); + /* :startdoc: */ rb_define_method(mReadable, "getch", io_getch, -1); rb_define_method(mReadable, "getpass", io_getpass, -1); }