Class: IO

Inherits:
Object
  • Object
show all
Defined in:
(unknown)

Defined Under Namespace

Modules: generic_readable Classes: ConsoleMode

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.console#<File:/dev/tty .console(sym, *args) ⇒ Object

Returns an File instance opened console.

If sym is given, it will be sent to the opened console with args and the result will be returned instead of the console IO itself.

You must require ‘io/console’ to use this method.

Overloads:

  • .console#<File:/dev/tty

    Returns ].

    Returns:

    • (#<File:/dev/tty)

      ]



1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
# File 'ext/io/console/console.c', line 1648

static VALUE
console_dev(int argc, VALUE *argv, VALUE klass)
{
    VALUE con = 0;
    VALUE sym = 0;

    rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS);

    if (argc) {
        Check_Type(sym = argv[0], T_SYMBOL);
    }

    // Force the class to be File.
    if (klass == rb_cIO) klass = rb_cFile;

    if (console_dev_get(klass, &con)) {
        if (!RB_TYPE_P(con, T_FILE) || RTEST(rb_io_closed_p(con))) {
	    console_dev_remove(klass);
            con = 0;
        }
    }

    if (sym) {
        if (sym == ID2SYM(id_close) && argc == 1) {
            if (con) {
                rb_io_close(con);
                console_dev_remove(klass);
                con = 0;
            }
            return Qnil;
        }
    }

    if (!con) {
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
# define CONSOLE_DEVICE "/dev/tty"
#elif defined _WIN32
# define CONSOLE_DEVICE "con$"
# define CONSOLE_DEVICE_FOR_READING "conin$"
# define CONSOLE_DEVICE_FOR_WRITING "conout$"
#endif
#ifndef CONSOLE_DEVICE_FOR_READING
# define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE
#endif
#ifdef CONSOLE_DEVICE_FOR_WRITING
        VALUE out;
#endif
        int fd;
        VALUE path = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));

#ifdef CONSOLE_DEVICE_FOR_WRITING
        fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
        if (fd < 0) return Qnil;
        out = rb_io_open_descriptor(klass, fd, FMODE_WRITABLE | FMODE_SYNC, path, Qnil, NULL);
#endif
        fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
        if (fd < 0) {
#ifdef CONSOLE_DEVICE_FOR_WRITING
            rb_io_close(out);
#endif
            return Qnil;
        }

        con = rb_io_open_descriptor(klass, fd, FMODE_READWRITE | FMODE_SYNC, path, Qnil, NULL);
#ifdef CONSOLE_DEVICE_FOR_WRITING
        rb_io_set_write_io(con, out);
#endif
        console_dev_set(klass, con);
    }

    if (sym) {
        return rb_f_send(argc, argv, con);
    }

    return con;
}

.default_console_sizeObject

fallback to console window size



3
4
5
6
7
8
# File 'lib/io/console/size.rb', line 3

def IO.default_console_size
  [
    ENV["LINES"].to_i.nonzero? || 25,
    ENV["COLUMNS"].to_i.nonzero? || 80,
  ]
end

Instance Method Details

#beepObject

Beeps on the output console.

You must require ‘io/console’ to use this method.



1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
# File 'ext/io/console/console.c', line 1021

static VALUE
console_beep(VALUE io)
{
#ifdef _WIN32
    MessageBeep(0);
#else
    int fd = GetWriteFD(io);
    if (write(fd, "\a", 1) < 0) sys_fail(io);
#endif
    return 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.

Yields:

Returns:



927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
# File 'ext/io/console/console.c', line 927

static VALUE
console_check_winsize_changed(VALUE io)
{
    HANDLE h;
    DWORD num;

    h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(io));
    while (GetNumberOfConsoleInputEvents(h, &num) && num > 0) {
	INPUT_RECORD rec;
	if (ReadConsoleInput(h, &rec, 1, &num)) {
	    if (rec.EventType == WINDOW_BUFFER_SIZE_EVENT) {
		rb_yield(Qnil);
	    }
	}
    }
    return io;
}

#clear_screenIO

Clears the entire screen and moves the cursor top-left corner.

You must require ‘io/console’ to use this method.

Returns:



1541
1542
1543
1544
1545
1546
1547
# File 'ext/io/console/console.c', line 1541

static VALUE
console_clear_screen(VALUE io)
{
    console_erase_screen(io, INT2FIX(2));
    console_goto(io, INT2FIX(0), INT2FIX(0));
    return io;
}

#console_modeObject

Returns a data represents the current console mode.

You must require ‘io/console’ to use this method.



773
774
775
776
777
778
779
780
781
782
# File 'ext/io/console/console.c', line 773

static VALUE
console_conmode_get(VALUE io)
{
    conmode t;
    int fd = GetReadFD(io);

    if (!getattr(fd, &t)) sys_fail(io);

    return conmode_new(cConmode, &t);
}

#console_mode=(mode) ⇒ Object

Sets the console mode to mode.

You must require ‘io/console’ to use this method.



792
793
794
795
796
797
798
799
800
801
802
803
804
# File 'ext/io/console/console.c', line 792

static VALUE
console_conmode_set(VALUE io, VALUE mode)
{
    conmode *t, r;
    int fd = GetReadFD(io);

    TypedData_Get_Struct(mode, conmode, &conmode_type, t);
    r = *t;

    if (!setattr(fd, &r)) sys_fail(io);

    return mode;
}

#cooked {|io| ... } ⇒ Object

Yields self within cooked mode.

STDIN.cooked(&:gets)

will read and return a line with echo back and line editing.

You must require ‘io/console’ to use this method.

Yields:

  • (io)


495
496
497
498
499
# File 'ext/io/console/console.c', line 495

static VALUE
console_cooked(VALUE io)
{
    return ttymode(io, rb_yield, io, set_cookedmode, NULL);
}

#cooked!Object

Enables cooked mode.

If the terminal mode needs to be back, use io.cooked { … }.

You must require ‘io/console’ to use this method.



511
512
513
514
515
516
517
518
519
520
# File 'ext/io/console/console.c', line 511

static VALUE
console_set_cooked(VALUE io)
{
    conmode t;
    int fd = GetReadFD(io);
    if (!getattr(fd, &t)) sys_fail(io);
    set_cookedmode(&t, NULL);
    if (!setattr(fd, &t)) sys_fail(io);
    return io;
}

#cursorArray

Returns the current cursor position as a two-element array of integers (row, column)

io.cursor # => [3, 5]

You must require ‘io/console’ to use this method.

Returns:

  • (Array)


1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
# File 'ext/io/console/console.c', line 1215

static VALUE
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};
    VALUE resp = console_vt_response(0, 0, io, &query);
    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;
    if (RSTRING_PTR(term)[0] != 'R') return Qnil;
    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;
#endif
}

#cursor=(cpos) ⇒ Object

Same as io.goto(line, column)

See IO#goto.

You must require ‘io/console’ to use this method.



1441
1442
1443
1444
1445
1446
1447
# File 'ext/io/console/console.c', line 1441

static VALUE
console_cursor_set(VALUE io, VALUE cpos)
{
    cpos = rb_convert_type(cpos, T_ARRAY, "Array", "to_ary");
    if (RARRAY_LEN(cpos) != 2) rb_raise(rb_eArgError, "expected 2D coordinate");
    return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1));
}

#cursor_down(n) ⇒ IO

Moves the cursor down n lines.

You must require ‘io/console’ to use this method.

Returns:



1471
1472
1473
1474
1475
# File 'ext/io/console/console.c', line 1471

static VALUE
console_cursor_down(VALUE io, VALUE val)
{
    return console_move(io, +NUM2INT(val), 0);
}

#cursor_left(n) ⇒ IO

Moves the cursor left n columns.

You must require ‘io/console’ to use this method.

Returns:



1485
1486
1487
1488
1489
# File 'ext/io/console/console.c', line 1485

static VALUE
console_cursor_left(VALUE io, VALUE val)
{
    return console_move(io, 0, -NUM2INT(val));
}

#cursor_right(n) ⇒ IO

Moves the cursor right n columns.

You must require ‘io/console’ to use this method.

Returns:



1499
1500
1501
1502
1503
# File 'ext/io/console/console.c', line 1499

static VALUE
console_cursor_right(VALUE io, VALUE val)
{
    return console_move(io, 0, +NUM2INT(val));
}

#cursor_up(n) ⇒ IO

Moves the cursor up n lines.

You must require ‘io/console’ to use this method.

Returns:



1457
1458
1459
1460
1461
# File 'ext/io/console/console.c', line 1457

static VALUE
console_cursor_up(VALUE io, VALUE val)
{
    return console_move(io, -NUM2INT(val), 0);
}

#echo=(flag) ⇒ Object

Enables/disables echo back. On some platforms, all combinations of this flags and raw/cooked mode may not be valid.

You must require ‘io/console’ to use this method.



666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
# File 'ext/io/console/console.c', line 666

static VALUE
console_set_echo(VALUE io, VALUE f)
{
    conmode t;
    int fd = GetReadFD(io);

    if (!getattr(fd, &t)) sys_fail(io);

    if (RTEST(f))
        set_echo(&t, NULL);
    else
        set_noecho(&t, NULL);

    if (!setattr(fd, &t)) sys_fail(io);

    return io;
}

#echo?Boolean

Returns true if echo back is enabled.

You must require ‘io/console’ to use this method.

Returns:

  • (Boolean)


692
693
694
695
696
697
698
699
700
# File 'ext/io/console/console.c', line 692

static VALUE
console_echo_p(VALUE io)
{
    conmode t;
    int fd = GetReadFD(io);

    if (!getattr(fd, &t)) sys_fail(io);
    return echo_p(&t) ? Qtrue : Qfalse;
}

#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.

Returns:



1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
# File 'ext/io/console/console.c', line 1342

static VALUE
console_erase_line(VALUE io, VALUE val)
{
    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(CSI "%dK", mode));
#endif
    return 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.

Returns:



1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
# File 'ext/io/console/console.c', line 1389

static VALUE
console_erase_screen(VALUE io, VALUE val)
{
    int mode = mode_in_range(val, 3, "screen 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:	/* 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(CSI "%dJ", mode));
#endif
    return io;
}

#getch(min: nil, time: nil, intr: nil) ⇒ String

Reads and returns a character in raw mode.

See IO#raw for details on the parameters.

You must require ‘io/console’ to use this method.

Returns:

  • (String)


561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
# File 'ext/io/console/console.c', line 561

static VALUE
console_getch(int argc, VALUE *argv, VALUE io)
{
    rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
#ifndef _WIN32
    return ttymode(io, getc_call, io, set_rawmode, optp);
#else
    rb_io_t *fptr;
    VALUE str;
    wint_t c;
    int len;
    char buf[8];
    wint_t wbuf[2];
# ifndef HAVE_RB_IO_WAIT
    struct timeval *to = NULL, tv;
# else
    VALUE timeout = Qnil;
# endif

    GetOpenFile(io, fptr);
    if (optp) {
	if (optp->vtime) {
# ifndef HAVE_RB_IO_WAIT
	    to = &tv;
# else
	    struct timeval tv;
# endif
	    tv.tv_sec = optp->vtime / 10;
	    tv.tv_usec = (optp->vtime % 10) * 100000;
# ifdef HAVE_RB_IO_WAIT
	    timeout = rb_fiber_scheduler_make_timeout(&tv);
# endif
	}
	switch (optp->vmin) {
	  case 1: /* default */
	    break;
	  case 0: /* return nil when timed out */
	    if (optp->vtime) break;
	    /* fallthru */
	  default:
	    rb_warning("min option larger than 1 ignored");
	}
	if (optp->intr) {
# ifndef HAVE_RB_IO_WAIT
	    int w = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, to);
	    if (w < 0) rb_eof_error();
	    if (!(w & RB_WAITFD_IN)) return Qnil;
# else
	    VALUE result = rb_io_wait(io, RB_INT2NUM(RUBY_IO_READABLE), timeout);
	    if (!RTEST(result)) return Qnil;
# endif
	}
	else if (optp->vtime) {
	    rb_warning("Non-zero vtime option ignored if intr flag is unset");
	}
    }
    len = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getch, wbuf, RUBY_UBF_IO, 0);
    switch (len) {
      case 0:
	return Qnil;
      case 2:
	buf[0] = (char)wbuf[0];
	c = wbuf[1];
	len = 1;
	do {
	    buf[len++] = (unsigned char)c;
	} while ((c >>= CHAR_BIT) && len < (int)sizeof(buf));
	return rb_str_new(buf, len);
      default:
	c = wbuf[0];
	len = rb_uv_to_utf8(buf, c);
	str = rb_utf8_str_new(buf, len);
	return rb_str_conv_enc(str, NULL, rb_default_external_encoding());
    }
#endif
}

#getpass(prompt = nil) ⇒ String

Reads and returns a line without echo back. Prints prompt unless it is nil.

The newline character that terminates the read line is removed from the returned string, see String#chomp!.

You must require ‘io/console’ to use this method.

require 'io/console'
IO::console.getpass("Enter password:")
Enter password:
# => "mypassword"

Returns:

  • (String)


1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
# File 'ext/io/console/console.c', line 1794

static VALUE
console_getpass(int argc, VALUE *argv, VALUE io)
{
    VALUE str, wio;

    rb_check_arity(argc, 0, 1);
    wio = rb_io_get_write_io(io);
    if (wio == io && io == rb_stdin) wio = rb_stderr;
    prompt(argc, argv, wio);
    rb_io_flush(wio);
    str = rb_ensure(getpass_call, io, puts_call, wio);
    return str_chomp(str);
}

#goto(line, column) ⇒ IO

Set the cursor position at line and column.

You must require ‘io/console’ to use this method.

Returns:



1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
# File 'ext/io/console/console.c', line 1253

static VALUE
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(CSI "%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1));
#endif
    return 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.

Returns:



1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
# File 'ext/io/console/console.c', line 1308

static VALUE
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(CSI "%dG", NUM2UINT(val)+1));
#endif
    return io;
}

#iflushObject

Flushes input buffer in kernel.

You must require ‘io/console’ to use this method.



956
957
958
959
960
961
962
963
964
965
# File 'ext/io/console/console.c', line 956

static VALUE
console_iflush(VALUE io)
{
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    int fd = GetReadFD(io);
    if (tcflush(fd, TCIFLUSH)) sys_fail(io);
#endif

    return io;
}

#ioflushObject

Flushes input and output buffers in kernel.

You must require ‘io/console’ to use this method.



994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
# File 'ext/io/console/console.c', line 994

static VALUE
console_ioflush(VALUE io)
{
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    int fd1 = GetReadFD(io);
    int fd2 = GetWriteFD(io);

    if (fd2 != -1 && fd1 != fd2) {
        if (tcflush(fd1, TCIFLUSH)) sys_fail(io);
        if (tcflush(fd2, TCOFLUSH)) sys_fail(io);
    }
    else {
        if (tcflush(fd1, TCIOFLUSH)) sys_fail(io);
    }
#endif

    return io;
}

#noecho {|io| ... } ⇒ Object

Yields self with disabling echo back.

STDIN.noecho(&:gets)

will read and return a line without echo back.

You must require ‘io/console’ to use this method.

Yields:

  • (io)


650
651
652
653
654
# File 'ext/io/console/console.c', line 650

static VALUE
console_noecho(VALUE io)
{
    return ttymode(io, rb_yield, io, set_noecho, NULL);
}

#oflushObject

Flushes output buffer in kernel.

You must require ‘io/console’ to use this method.



975
976
977
978
979
980
981
982
983
984
# File 'ext/io/console/console.c', line 975

static VALUE
console_oflush(VALUE io)
{
    int fd = GetWriteFD(io);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    if (tcflush(fd, TCOFLUSH)) sys_fail(io);
#endif
    (void)fd;
    return io;
}

#pressed?(key) ⇒ Boolean

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.

Returns:

  • (Boolean)


1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
# File 'ext/io/console/console.c', line 1102

static VALUE
console_key_pressed_p(VALUE io, VALUE k)
{
    int vk = -1;

    if (FIXNUM_P(k)) {
	vk = NUM2UINT(k);
    }
    else {
	const struct vktable *t;
	const char *kn;
	if (SYMBOL_P(k)) {
	    k = rb_sym2str(k);
	    kn = RSTRING_PTR(k);
	}
	else {
	    kn = StringValuePtr(k);
	}
	t = console_win32_vk(kn, RSTRING_LEN(k));
	if (!t || (vk = (short)t->vk) == -1) {
	    rb_raise(rb_eArgError, "unknown virtual key code: % "PRIsVALUE, k);
	}
    }
    return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse;
}

#raw(min: nil, time: nil, intr: nil) {|io| ... } ⇒ Object

Yields self within raw mode, and returns the result of the block.

STDIN.raw(&:gets)

will read and return a line without echo back and line editing.

The parameter min specifies the minimum number of bytes that should be received when a read operation is performed. (default: 1)

The parameter time specifies the timeout in seconds with a precision of 1/10 of a second. (default: 0)

If the parameter intr is true, enables break, interrupt, quit, and suspend special characters.

Refer to the manual page of termios for further details.

You must require ‘io/console’ to use this method.

Yields:

  • (io)


452
453
454
455
456
457
# File 'ext/io/console/console.c', line 452

static VALUE
console_raw(int argc, VALUE *argv, VALUE io)
{
    rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
    return ttymode(io, rb_yield, io, set_rawmode, optp);
}

#raw!(min: nil, time: nil, intr: nil) ⇒ IO

Enables raw mode, and returns io.

If the terminal mode needs to be back, use io.raw { ... }.

See IO#raw for details on the parameters.

You must require ‘io/console’ to use this method.

Returns:



471
472
473
474
475
476
477
478
479
480
481
# File 'ext/io/console/console.c', line 471

static VALUE
console_set_raw(int argc, VALUE *argv, VALUE io)
{
    conmode t;
    rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
    int fd = GetReadFD(io);
    if (!getattr(fd, &t)) sys_fail(io);
    set_rawmode(&t, optp);
    if (!setattr(fd, &t)) sys_fail(io);
    return io;
}

#scroll_backward(n) ⇒ IO

Scrolls the entire scrolls backward n lines.

You must require ‘io/console’ to use this method.

Returns:



1527
1528
1529
1530
1531
# File 'ext/io/console/console.c', line 1527

static VALUE
console_scroll_backward(VALUE io, VALUE val)
{
    return console_scroll(io, -NUM2INT(val));
}

#scroll_forward(n) ⇒ IO

Scrolls the entire scrolls forward n lines.

You must require ‘io/console’ to use this method.

Returns:



1513
1514
1515
1516
1517
# File 'ext/io/console/console.c', line 1513

static VALUE
console_scroll_forward(VALUE io, VALUE val)
{
    return console_scroll(io, +NUM2INT(val));
}

#ttynameString?

Returns name of associated terminal (tty) if io is not a tty. Returns nil otherwise.

Returns:

  • (String, nil)


1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
# File 'ext/io/console/console.c', line 1834

static VALUE
console_ttyname(VALUE io)
{
    int fd = rb_io_descriptor(io);
    if (!isatty(fd)) return Qnil;
# if defined _WIN32
    return rb_usascii_str_new_lit("con");
# elif defined HAVE_TTYNAME_R
    {
	char termname[1024], *tn = termname;
	size_t size = sizeof(termname);
	int e;
	if (ttyname_r(fd, tn, size) == 0)
	    return rb_interned_str_cstr(tn);
	if ((e = errno) == ERANGE) {
	    VALUE s = rb_str_new(0, size);
	    while (1) {
		tn = RSTRING_PTR(s);
		size = rb_str_capacity(s);
		if (ttyname_r(fd, tn, size) == 0) {
		    return rb_str_to_interned_str(rb_str_resize(s, strlen(tn)));
		}
		if ((e = errno) != ERANGE) break;
		if ((size *= 2) >= INT_MAX/2) break;
		rb_str_resize(s, size);
	    }
	}
	rb_syserr_fail_str(e, rb_sprintf("ttyname_r(%d)", fd));
	UNREACHABLE_RETURN(Qnil);
    }
# elif defined HAVE_TTYNAME
    {
	const char *tn = ttyname(fd);
	if (!tn) {
	    int e = errno;
	    rb_syserr_fail_str(e, rb_sprintf("ttyname(%d)", fd));
	}
	return rb_interned_str_cstr(tn);
    }
# else
#   error No ttyname function
# endif
}

#winsizeArray

Returns console size.

You must require ‘io/console’ to use this method.

Returns:

  • (Array)


834
835
836
837
838
839
840
841
# File 'ext/io/console/console.c', line 834

static VALUE
console_winsize(VALUE io)
{
    rb_console_size_t ws;
    int fd = GetWriteFD(io);
    if (!getwinsize(fd, &ws)) sys_fail(io);
    return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
}

#winsize=(size) ⇒ Object

Tries to set console size. The effect depends on the platform and the running environment.

You must require ‘io/console’ to use this method.



852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
# File 'ext/io/console/console.c', line 852

static VALUE
console_set_winsize(VALUE io, VALUE size)
{
    rb_console_size_t ws;
#if defined _WIN32
    HANDLE wh;
    int newrow, newcol;
    BOOL ret;
#endif
    VALUE row, col, xpixel, ypixel;
    const VALUE *sz;
    long sizelen;
    int fd;

    size = rb_Array(size);
    if ((sizelen = RARRAY_LEN(size)) != 2 && sizelen != 4) {
        rb_raise(rb_eArgError, "wrong number of arguments (given %ld, expected 2 or 4)", sizelen);
    }
    sz = RARRAY_CONST_PTR(size);
    row = sz[0], col = sz[1], xpixel = ypixel = Qnil;
    if (sizelen == 4) xpixel = sz[2], ypixel = sz[3];
    fd = GetWriteFD(io);
#if defined TIOCSWINSZ
    ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0;
#define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
    SET(row);
    SET(col);
    SET(xpixel);
    SET(ypixel);
#undef SET
    if (!setwinsize(fd, &ws)) sys_fail(io);
#elif defined _WIN32
    wh = (HANDLE)rb_w32_get_osfhandle(fd);
#define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
    SET(row);
    SET(col);
#undef SET
    if (!NIL_P(xpixel)) (void)NUM2UINT(xpixel);
    if (!NIL_P(ypixel)) (void)NUM2UINT(ypixel);
    if (!GetConsoleScreenBufferInfo(wh, &ws)) {
	rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo");
    }
    ws.dwSize.X = newcol;
    ret = SetConsoleScreenBufferSize(wh, ws.dwSize);
    ws.srWindow.Left = 0;
    ws.srWindow.Top = 0;
    ws.srWindow.Right = newcol-1;
    ws.srWindow.Bottom = newrow-1;
    if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) {
	rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo");
    }
    /* retry when shrinking buffer after shrunk window */
    if (!ret && !SetConsoleScreenBufferSize(wh, ws.dwSize)) {
	rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo");
    }
    /* remove scrollbar if possible */
    if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) {
	rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo");
    }
#endif
    return io;
}