class TermInfo

Attributes

io[R]

Public Class Methods

control(*args) click to toggle source
# File lib/terminfo.rb, line 44
def TermInfo.control(*args) default_object.control(*args) end
control_string(*args) click to toggle source
# File lib/terminfo.rb, line 43
def TermInfo.control_string(*args) default_object.control_string(*args) end
ctermid() click to toggle source

::ctermid

::ctermid returns a pathname for the current controling terminal, such as “/dev/tty”.

static VALUE
rt_ctermid(VALUE self)
{
#ifdef HAVE_CTERMID
  char buf[L_ctermid];
  return rb_str_new2(ctermid(buf));
#else
  return rb_str_new2("/dev/tty");
#endif
}
default_object() click to toggle source
# 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
flush(&block) click to toggle source
# File lib/terminfo.rb, line 46
def TermInfo.flush(&block) default_object.flush(&block) end
io() click to toggle source
# File lib/terminfo.rb, line 52
def TermInfo.io() default_object.io() end
new(term=ENV['TERM'], io=STDERR) click to toggle source
# File lib/terminfo.rb, line 54
def initialize(term=ENV['TERM'], io=STDERR)
  setupterm(term, io.fileno)
  @term = term
  @io = io
end
screen_columns() click to toggle source
# File lib/terminfo.rb, line 50
def TermInfo.screen_columns() default_object.screen_columns() end
screen_height() click to toggle source
# File lib/terminfo.rb, line 49
def TermInfo.screen_height() default_object.screen_height() end
screen_lines() click to toggle source
# File lib/terminfo.rb, line 48
def TermInfo.screen_lines() default_object.screen_lines() end
screen_size() click to toggle source
# File lib/terminfo.rb, line 47
def TermInfo.screen_size() default_object.screen_size() end
screen_width() click to toggle source
# File lib/terminfo.rb, line 51
def TermInfo.screen_width() default_object.screen_width() end
tiocgwinsz(p1) click to toggle source

::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(p1, p2, p3) click to toggle source

::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(p1) click to toggle source

::wcswidth

::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);
}
write(str) click to toggle source
# File lib/terminfo.rb, line 45
def TermInfo.write(str) default_object.write(str) end

Public Instance Methods

control(*args) click to toggle source

#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(*args) click to toggle source

#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
flush() { || ... } click to toggle source
# 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
inspect() click to toggle source
# File lib/terminfo.rb, line 61
def inspect
  "\#<#{self.class}:#{@term}>"
end
screen_columns() click to toggle source

returns terminal screen width.

# File lib/terminfo.rb, line 136
def screen_columns
  self.screen_size[1]
end
Also aliased as: screen_width
screen_height()
Alias for: screen_lines
screen_lines() click to toggle source

returns terminal screen height.

# File lib/terminfo.rb, line 130
def screen_lines
  self.screen_size[0]
end
Also aliased as: screen_height
screen_size() click to toggle source

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
screen_width()
Alias for: screen_columns
setupterm(p1, p2) click to toggle source

#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(p1) click to toggle source

#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(p1) click to toggle source

#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(p1) click to toggle source

#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(p1, p2 = v2, p3 = v3, p4 = v4, p5 = v5, p6 = v6, p7 = v7, p8 = v8, p9 = v9, p10 = v10) click to toggle source

#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(p1, p2) click to toggle source

#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;
}
write(str) click to toggle source
# File lib/terminfo.rb, line 91
def write(str)
  @io.write(str)
end