Nonblock_keyboard_map

The gem keyboard_map is used to translate keyboard sequences to keys and key-names.

If you choose to capture keyboard non-blocking.. you either import some curses library or tty-reader. Or you will have to spend a lot of time translating the received sequences.

How many chars? Two? Three? Is the first one Escape ("\e")? Is the second “[”? Is the second a printable char or a control char? Translate “^v” to “k”.

With keyboard_map it’s done for you. And the source code is relatively small.

Code below is an example. Two sections. The first is the fetch key in raw mode, no echo.
The second is the main loop and the KeyboardMap call.

In its current state, it just prints out the pressed key and the modifier keys (if any).

require 'io/console'
require 'keyboard_map'

module Enumerable
  alias :in? :include?
end

def read_ch
  chrs = []
  IO.console.noecho {
    IO.console.raw{|c|
      while ch = c.read_nonblock(1) rescue nil
        exit if ch == 'q'
        chrs << ch
      end
      # give the CPU some rest 
      chrs.empty? ? (sleep 0.05; nil) : chrs.join
    }
  }
end


kb = KeyboardMap.new

loop {
  if ch = read_ch
    # no not wait for further keys when single escape is recieved.
    ev = ch == "\e" ? (kb.finish; [:esc]) : kb.call(ch)
    ev.each {|e|
      case e
      when Symbol then p e
      when String then p e.force_encoding('UTF-8')
      else
        # modifiers and key is just printed here
        %i(ctrl meta).map {|mod| p mod if e.modifiers.in?(mod) }
        p [e.modifiers.to_a, e.key]
      end
    }
  end
}