Class: GLI::Terminal

Inherits:
Object
  • Object
show all
Defined in:
lib/gli/terminal.rb

Overview

Class to encapsulate stuff about the terminal. This is useful to application developers as a canonical means to get information about the user’s current terminal configuraiton. GLI uses this to determine the number of columns to use when printing to the screen.

To access it, use Terminal.instance. This is a singleton mostly to facilitate testing, but it seems reasonable enough, since there’s only one terminal in effect

Example:

Terminal.instance.size[0] # => columns in the terminal
Terminal.default_size = [128,24] # => change default when we can't figure it out
raise "no ls?!?!?" unless Terminal.instance.command_exists?("ls")

Constant Summary collapse

SIZE_DETERMINERS =
[
  [
    lambda { (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/) },
    lambda { [ENV['COLUMNS'].to_i, ENV['LINES'].to_i] }
  ],
  [
    lambda { (jruby? || (!STDIN.tty? && ENV['TERM'])) && command_exists?('tput') },
    lambda { [run_command('tput cols').to_i, run_command('tput lines').to_i] }
  ],
  [
    lambda { (solaris? && STDIN.tty? && command_exists?('stty')) },
    lambda { run_command('stty').split("\n")[1].scan(/\d+/)[0..1].map { |size_element| size_element.to_i }.reverse }
  ],
  [ 
    lambda { STDIN.tty? && command_exists?('stty') },
    lambda { run_command('stty size').scan(/\d+/).map { |size_element| size_element.to_i }.reverse }
  ],
  [
    lambda { true },
    lambda { Terminal.default_size },
  ],
]
@@default_size =
[80,24]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.command_exists?(command) ⇒ Boolean

Returns true if the given command exists on this system

command

The command, as a String, to check for, without any path information.

Returns:

  • (Boolean)


45
46
47
# File 'lib/gli/terminal.rb', line 45

def self.command_exists?(command)
  ENV['PATH'].split(File::PATH_SEPARATOR).any? {|dir| File.exist? File.join(dir, command) }
end

.default_sizeObject

Get the default size of the terminal when we can’t figure it out

Returns an array of int [cols,rows]



22
23
24
# File 'lib/gli/terminal.rb', line 22

def self.default_size
  @@default_size
end

.default_size=(size) ⇒ Object

Set the default size of the terminal to use when we can’t figure it out

size

array of two int [cols,rows]



29
30
31
# File 'lib/gli/terminal.rb', line 29

def self.default_size=(size)
  @@default_size = size
end

.instanceObject

Provide access to the shared instance.



34
# File 'lib/gli/terminal.rb', line 34

def self.instance; @@instance ||= Terminal.new; end

Instance Method Details

#command_exists?(command) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/gli/terminal.rb', line 49

def command_exists?(command)
  self.class.command_exists?(command)
end

#make_unsafe!Object

Call this to cause methods to throw exceptions rather than return a sane default. You probably don’t want to call this unless you are writing tests



38
39
40
# File 'lib/gli/terminal.rb', line 38

def make_unsafe! #:nodoc:
  @unsafe = true
end

#sizeObject

Get the size of the current terminal. Ripped from hirb

Returns an Array of size two Ints representing the terminal width and height



80
81
82
83
84
85
86
87
88
89
# File 'lib/gli/terminal.rb', line 80

def size
  SIZE_DETERMINERS.each do |predicate, get_size|
    next unless predicate.call
    size = get_size.call
    return size unless size == [0, 0]
  end
rescue Exception => ex
  raise ex if @unsafe
  Terminal.default_size
end