Reputation: 1486
I am in a Ruby script something like:
something = gets # or STDIN.gets
puts something
def arrow_pressed
puts "arrow totally pressed"
end
Once the user prompt exists I want all keyboard input to happen normally except for the arrow keys. If those are pressed I don't want anything to appear in the terminal (e.g. ^[[A
). I just want to execute my arrow_pressed
method. And I want to execute it without the user needing to hit Return
I already tried this gist - which works well except that even after changing it to let through most keystrokes normally, I still can't get Backspace
(or other specials) to work.
I'm happy to use something other than gets
(a library or whatever). Any help would be appreciated!
Upvotes: 4
Views: 2175
Reputation: 547
I'm the author of tty-reader that provides a higher-level API for handling keyboard input. Using it you can read a single keypress, entire line or multiline content. It also allows you to listen for different key events like key up or backspace.
For example, to prompt the user for input and perform actions when arrows or backspace are pressed:
require "tty-reader"
reader = TTY::Reader.new
reader.on(:keydown) { puts "down we go" }
.on(:keyup) { puts "up we go" }
.on(:keybackspace) { puts "backspace pressed" }
answer = reader.read_line
The gem has been tested to work on all major platforms including Windows.
Upvotes: 5
Reputation: 114178
You could use getch
but since arrow keys are given as ANSI escape sequences, some parsing is required:
require 'io/console'
loop do
case $stdin.getch
when 'q' then exit
when "\c?" then puts 'backspace'
when "\e" # ANSI escape sequence
case $stdin.getch
when '[' # CSI
case $stdin.getch
when 'A' then puts 'up'
when 'B' then puts 'down'
when 'C' then puts 'right'
when 'D' then puts 'left'
end
end
end
end
This is just an example. There are many other escape sequences you'll have to consider.
Upvotes: 3