Class: FunCi::Tui::TerminalInput

Inherits:
Object
  • Object
show all
Defined in:
lib/fun_ci/tui/terminal_input.rb

Instance Method Summary collapse

Constructor Details

#initialize(input:, width_provider: nil) ⇒ TerminalInput

Returns a new instance of TerminalInput.



6
7
8
9
10
11
# File 'lib/fun_ci/tui/terminal_input.rb', line 6

def initialize(input:, width_provider: nil)
  @input = input
  @width_provider = width_provider
  @signal_read = nil
  @signal_write = nil
end

Instance Method Details

#check_width ⇒ Object



22
23
24
25
26
# File 'lib/fun_ci/tui/terminal_input.rb', line 22

def check_width
  return nil unless @width_provider

  @width_provider.call
end

#read_key_with_timeout(timeout) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/fun_ci/tui/terminal_input.rb', line 40

def read_key_with_timeout(timeout)
  return nil unless @input.respond_to?(:read_nonblock)

  watched = [@input]
  watched << @signal_read if @signal_read
  ready = IO.select(watched, nil, nil, timeout)
  return nil unless ready

  if @signal_read && ready[0].include?(@signal_read)
    @signal_read.read_nonblock(1) rescue nil # rubocop:disable Style/RescueModifier
    return nil unless ready[0].include?(@input)
  end

  byte = @input.read_nonblock(1)
  if byte == "\e"
    seq = @input.read_nonblock(2) rescue "" # rubocop:disable Style/RescueModifier
    case seq
    when "[A" then :up
    when "[B" then :down
    else :escape
    end
  else
    byte
  end
rescue IO::WaitReadable, EOFError
  nil
end

#restore_terminal ⇒ Object



34
35
36
37
38
# File 'lib/fun_ci/tui/terminal_input.rb', line 34

def restore_terminal
  @input.cooked! if @input.respond_to?(:cooked!)
rescue Errno::ENOTTY
  # Not a terminal
end

#setup_raw_mode ⇒ Object



28
29
30
31
32
# File 'lib/fun_ci/tui/terminal_input.rb', line 28

def setup_raw_mode
  @input.raw! if @input.respond_to?(:raw!)
rescue Errno::ENOTTY
  # Not a terminal (testing)
end

#setup_signal_trap ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/fun_ci/tui/terminal_input.rb', line 13

def setup_signal_trap
  return unless @width_provider

  @signal_read, @signal_write = IO.pipe
  Signal.trap("WINCH") do
    @signal_write&.write_nonblock(".") rescue nil # rubocop:disable Style/RescueModifier
  end
end