Class: Keisanjaku::Input

Inherits:
Object
  • Object
show all
Defined in:
lib/keisanjaku/input.rb

Constant Summary collapse

CRLF =
"\r\n"
CSI_MAP =
{
  "\e[A" => :up,
  "\e[B" => :down,
  "\e[C" => :right,
  "\e[D" => :left,
  "\e[H" => :home,
  "\e[F" => :end,
  "\e[3~" => :delete
}.freeze
SIMPLE_MAP =
{
  "\r" => :enter,
  "\n" => :enter,
  "\t" => :tab,
  "\u007F" => :backspace,
  "\e" => :escape,
  " " => :space
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io = $stdin) ⇒ Input

Returns a new instance of Input.



27
28
29
# File 'lib/keisanjaku/input.rb', line 27

def initialize(io = $stdin)
  @io = io
end

Class Method Details

.decode_sequence(sequence) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/keisanjaku/input.rb', line 46

def self.decode_sequence(sequence)
  return CSI_MAP[sequence] if CSI_MAP.key?(sequence)
  return SIMPLE_MAP[sequence] if SIMPLE_MAP.key?(sequence)
  return :ctrl_c if sequence == "\u0003"

  sequence
end

.raw_print_lines(output, lines) ⇒ Object



74
75
76
# File 'lib/keisanjaku/input.rb', line 74

def self.raw_print_lines(output, lines)
  lines.each { |line| raw_puts(output, line) }
end

.raw_puts(output, value = "") ⇒ Object



69
70
71
72
# File 'lib/keisanjaku/input.rb', line 69

def self.raw_puts(output, value = "")
  output.print value.to_s
  output.print CRLF
end

.with_raw(input: $stdin, output: $stdout, clear_on_exit: true) ⇒ Object



58
59
60
61
62
63
64
65
66
67
# File 'lib/keisanjaku/input.rb', line 58

def self.with_raw(input: $stdin, output: $stdout, clear_on_exit: true)
  output.print ANSI.hide_cursor
  input.raw do
    yield
  ensure
    output.print ANSI.clear_screen if clear_on_exit
    output.print ANSI.show_cursor
    output.flush
  end
end

Instance Method Details

#decode_sequence(sequence) ⇒ Object



54
55
56
# File 'lib/keisanjaku/input.rb', line 54

def decode_sequence(sequence)
  self.class.decode_sequence(sequence)
end

#read_key(timeout: nil) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/keisanjaku/input.rb', line 31

def read_key(timeout: nil)
  return nil if timeout && !@io.wait_readable(timeout)

  first = @io.getch
  return nil unless first
  return decode_sequence(first) unless first == "\e"

  sequence = first.dup
  while @io.wait_readable(0.01)
    sequence << @io.getch
    break if CSI_MAP.key?(sequence) || sequence.match?(/\A\e\[[0-9;]*[~A-Za-z]\z/)
  end
  decode_sequence(sequence)
end