class TermInfo
Attributes
Public Class Methods
# File lib/terminfo.rb, line 44 def TermInfo.control(*args) default_object.control(*args) end
# File lib/terminfo.rb, line 43 def TermInfo.control_string(*args) default_object.control_string(*args) end
# File lib/terminfo.rb, line 34 def TermInfo.default_object unless defined? @default_terminfo io = File.open(TermInfo.ctermid, File::RDWR|File::NOCTTY) io.sync = true @default_terminfo = TermInfo.new(ENV['TERM'], io) end @default_terminfo end
# File lib/terminfo.rb, line 46 def TermInfo.flush(&block) default_object.flush(&block) end
# File lib/terminfo.rb, line 52 def TermInfo.io() default_object.io() end
# File lib/terminfo.rb, line 54 def initialize(term=ENV['TERM'], io=STDERR) setupterm(term, io.fileno) @term = term @io = io end
# File lib/terminfo.rb, line 50 def TermInfo.screen_columns() default_object.screen_columns() end
# File lib/terminfo.rb, line 49 def TermInfo.screen_height() default_object.screen_height() end
# File lib/terminfo.rb, line 48 def TermInfo.screen_lines() default_object.screen_lines() end
# File lib/terminfo.rb, line 47 def TermInfo.screen_size() default_object.screen_size() end
# File lib/terminfo.rb, line 51 def TermInfo.screen_width() default_object.screen_width() end
::tiocgwinsz => [row, col]
::tiocgwinsz returns the screen size of the terminal refered by io, using TIOCGWINSZ ioctl.
static VALUE rt_tiocgwinsz(VALUE self, VALUE io) { #ifdef TIOCGWINSZ rb_io_t *fptr; struct winsize sz; int ret; GetOpenFile(io, fptr); ret = ioctl(FILENO(fptr), TIOCGWINSZ, &sz); if (ret == -1) rb_raise(rb_eIOError, "TIOCGWINSZ failed"); return rb_ary_new3(2, INT2NUM(sz.ws_row), INT2NUM(sz.ws_col)); #else rb_notimplement(); #endif }
::tiocswinsz(io, row, col)
::tiocgwinsz update the screen size information of the terminal refered by io, using TIOCSWINSZ ioctl.
It returns nil.
static VALUE rt_tiocswinsz(VALUE self, VALUE io, VALUE row, VALUE col) { #ifdef TIOCSWINSZ rb_io_t *fptr; struct winsize sz; int ret; GetOpenFile(io, fptr); sz.ws_row = NUM2INT(row); sz.ws_col = NUM2INT(col); ret = ioctl(FILENO(fptr), TIOCSWINSZ, &sz); if (ret == -1) rb_raise(rb_eIOError, "TIOCSWINSZ failed"); return Qnil; #else rb_notimplement(); #endif }
::wcswidth returns a the number of columns of str, according to current locale.
static VALUE rt_wcswidth(VALUE self, VALUE str) { char *s; size_t l, r; mbstate_t mbs; wchar_t wc; long cols; int width; #ifdef HAVE_RUBY_ENCODING_H /* The encoding of str is assumed to be the locale encoding on Ruby 1.8. */ str = rb_str_encode(str, rb_enc_from_encoding(rb_locale_encoding()), 0, Qnil); #endif memset(&mbs,0,sizeof(mbstate_t)); s = StringValueCStr(str); l = RSTRING_LEN(str); cols = 0; while (0 < l) { r = mbrtowc(&wc, s, l, &mbs); if (r == 0) rb_raise(rb_eArgError, "NUL found"); width = wcwidth(wc); if (width == -1) rb_raise(rb_eArgError, "non-printable charactor found"); cols += width; l -= r; s += r; } return LONG2NUM(cols); }
# File lib/terminfo.rb, line 45 def TermInfo.write(str) default_object.write(str) end
Public Instance Methods
#control controls a terminal.
It prints the result of ::control_string to io specified at initialization.
# File lib/terminfo.rb, line 86 def control(*args) @io.write(self.control_string(*args)) nil end
#control_string return a string to control terminal.
TermInfo#control_string([afflines,] capname, p1, p2, ...)
capname is a terminfo string capability such as “cuu”, “el”.
p1, p2, … are parameters for the capability.
afflines is a number of lines affected. (used for determining padding length)
# File lib/terminfo.rb, line 74 def control_string(*args) afflines = 1 raise ArgumentError, "capname requried" if args.empty? afflines = args.shift.to_i if args.first.respond_to?(:to_int) raise ArgumentError, "capname not given" if !args.first.respond_to?(:to_str) capname = args.shift.to_str self.tputs(self.tparm(self.tigetstr(capname), *args), afflines) end
# File lib/terminfo.rb, line 95 def flush oldlevel = nil if block_given? oldlevel = Thread.current[:TermInfo_Flush_level] oldsync = @io.sync begin Thread.current[:TermInfo_Flush_level] = (oldlevel || 0) + 1 @io.sync = false yield ensure Thread.current[:TermInfo_Flush_level] = oldlevel @io.sync = oldsync end end @io.flush if oldlevel == nil nil end
# File lib/terminfo.rb, line 61 def inspect "\#<#{self.class}:#{@term}>" end
returns terminal screen width.
# File lib/terminfo.rb, line 136 def screen_columns self.screen_size[1] end
returns terminal screen height.
# File lib/terminfo.rb, line 130 def screen_lines self.screen_size[0] end
returns terminal screen size in a two element array: [lines, columns].
# File lib/terminfo.rb, line 114 def screen_size begin size = TermInfo.tiocgwinsz(@io) rescue NotImplementedError size = [0,0] end if size[0] == 0 size[0] = ENV.include?('LINES') ? ENV['LINES'].to_i : self.tigetnum("lines") end if size[1] == 0 size[1] = ENV.include?('COLUMNS') ? ENV['COLUMNS'].to_i : self.tigetnum("cols") end size end
#setupterm(term, fd) => int
#setupterm initializes TermInfo object.
term is a string of nil. If nil is given, the environment variable $TERM is used.
fd is a file descriptor for target terminal.
static VALUE rt_setupterm(VALUE self, VALUE v_term, VALUE v_fd) { char *term; int fd; int err; int ret; if (check_rt(self) != NULL) { rb_raise(eTermInfoError, "terminfo object already initialized"); } if (v_term == Qnil) term = NULL; else term = StringValueCStr(v_term); fd = NUM2INT(v_fd); ret = setupterm(term, fd, &err); if (ret == ERR) { if (err == 1) rb_raise(eTermInfoError, "hardcopy terminal"); else if (err == 0) rb_raise(eTermInfoError, "terminal could not be found"); else if (err == -1) rb_raise(eTermInfoError, "terminfo database could not be found"); else rb_raise(eTermInfoError, "unexpected setupterm error"); } DATA_PTR(self) = cur_term; return INT2NUM(err); }
#tigetflag => int
#tigetflag returns a boolean capability specified by capname.
static VALUE rt_tigetflag(VALUE self, VALUE v_capname) { int ret; setup(self); ret = tigetflag(StringValueCStr(v_capname)); if (ret == -1) { rb_raise(eTermInfoError, "not a boolean capability"); } return RTEST(ret) ? Qtrue : Qfalse; }
#tigetnum => int
#tigetnum returns a numeric capability specified by capname.
static VALUE rt_tigetnum(VALUE self, VALUE v_capname) { int ret; setup(self); ret = tigetnum(StringValueCStr(v_capname)); if (ret == -2) { rb_raise(eTermInfoError, "not a numeric capability"); } if (ret == -1) { rb_raise(eTermInfoError, "canceled or absent numeric capability"); } return INT2NUM(ret); }
#tigetstr => str
#tigetstr returns a string capability specified by capname.
The return value should be printed after tputs is applied. Also tparm should be applied if it has parameters.
io.print ti.tputs(ti.tparm(ti.tigetstr("cuf"), 2))
Note that “cuf” means “cursor forward”.
static VALUE rt_tigetstr(VALUE self, VALUE v_capname) { char *ret; setup(self); ret = tigetstr(StringValueCStr(v_capname)); if (ret == (char*)-1) { rb_raise(eTermInfoError, "not a string capability"); } if (ret == 0) { rb_raise(eTermInfoError, "canceled or absent string capability"); } return rb_str_new2(ret); }
#tparm(str, …) => str
#tparm expands parameters in str returned by tigetstr.
static VALUE rt_tparm(int argc, VALUE *argv, VALUE self) { char *capname, *ret; setup(self); VALUE v_capname, v1, v2, v3, v4, v5, v6, v7, v8, v9; long p1, p2, p3, p4, p5, p6, p7, p8, p9; setup(self); if (rb_scan_args(argc, argv, "19", &v_capname, &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9) == 0) { rb_raise(rb_eArgError, "capname required"); } capname = StringValueCStr(v_capname); #define conv(p, v) do { if (v == Qnil) p = 0; else p = NUM2LONG(v); } while(0) conv(p1, v1); conv(p2, v2); conv(p3, v3); conv(p4, v4); conv(p5, v5); conv(p6, v6); conv(p7, v7); conv(p8, v8); conv(p9, v9); ret = tparm(capname, p1, p2, p3, p4, p5, p6, p7, p8, p9); if (ret == NULL) { rb_raise(eTermInfoError, "tparm failed"); } return rb_str_new2(ret); }
#tputs(str, affcnt) => str
#tputs expands padding informaiton using padding characters. affcnt is a number of lines affected by the str.
static VALUE rt_tputs(VALUE self, VALUE v_str, VALUE v_affcnt) { int ret; char *str; int affcnt; VALUE output; setup(self); str = StringValueCStr(v_str); affcnt = NUM2INT(v_affcnt); putfunc_output = output = rb_str_new2(""); ret = tputs(str, affcnt, putfunc); putfunc_output = Qnil; if (ret == ERR) { rb_raise(eTermInfoError, "tputs failed"); } return output; }
# File lib/terminfo.rb, line 91 def write(str) @io.write(str) end