Class: Foruiman::TUI::Keyboard

Inherits:
Object
  • Object
show all
Defined in:
lib/foruiman/tui/keyboard.rb

Constant Summary collapse

SEQUENCES =
{
  "\e[A" => :up, "\e[B" => :down, "\e[C" => :next, "\e[D" => :previous,
  "\e[5~" => :page_up, "\e[6~" => :page_down, "\e[H" => :home, "\e[F" => :end,
  "\e[1~" => :home, "\e[4~" => :end, "\eOH" => :home, "\eOF" => :end,
  "\e[Z" => :previous
}.freeze
KEYS =
{
  "\t" => :next, "h" => :previous, "l" => :next, "k" => :up, "j" => :down,
  "g" => :home, "G" => :end, "f" => :follow, " " => :toggle_follow,
  "r" => :restart, "R" => :restart_all, "s" => :stop, "S" => :stop_all,
  "i" => :input, "?" => :help, "q" => :quit, "\x03" => :quit,
  "\x15" => :page_up, "\x04" => :page_down
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Keyboard

Returns a new instance of Keyboard.



19
20
21
22
# File 'lib/foruiman/tui/keyboard.rb', line 19

def initialize
  @buffer = +"".b
  @escape_at = nil
end

Instance Method Details

#feed(bytes, now: monotonic) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/foruiman/tui/keyboard.rb', line 24

def feed(bytes, now: monotonic)
  @buffer << bytes
  actions = []
  until @buffer.empty?
    if @buffer.start_with?("\e")
      sequence = SEQUENCES.keys.find { |key| @buffer.start_with?(key) }
      if sequence
        actions << SEQUENCES.fetch(sequence)
        @buffer.slice!(0, sequence.bytesize)
      elsif incomplete_escape?
        @escape_at ||= now
        break if now - @escape_at < 0.1 && @buffer.bytesize < 64

        actions << :escape if @buffer == "\e"
        @buffer.clear
      else
        # Ignore an unknown complete escape as a unit; its final byte must
        # never accidentally become a destructive shortcut such as R.
        match = @buffer.match(%r{\A\e(?:\[[0-?]*[ -/]*[@-~]|O.|.)}m)
        @buffer.slice!(0, match ? match[0].bytesize : 1)
      end
    else
      key = @buffer.slice!(0, 1)
      actions << (key.match?(/[0-9]/) ? key.to_i : KEYS[key])
    end
    @escape_at = nil
  end
  actions.compact
end