2012-01-02 61 views
3

我正在Ruby中编写一个小脚本,它从命令行读取输入。捕获Ruby脚本中的箭头键事件

我想抓住上,下,左,右箭头信号。我想在终端上做类似的事情。 (当你点击箭头时,你有以前的命令......) 我该怎么做?

+0

你要像[GNU的readline(http://www.gnu.org/s/readline/)?另外,你的目标是什么操作系统? – 2012-01-02 14:20:51

+0

对于Linux,请参阅http://stackoverflow.com/questions/897687/ruby-keyboard-event-handling – 2012-01-02 14:25:39

+0

如果你想要的只是命令repitition,我认为'gets'为你提供。 – itdoesntwork 2012-01-02 15:44:17

回答

2

要做完全无缓冲的输入,你可以使用类似termios的东西。但是,您必须手动解释箭头键序列。

如果你能与历史完成一个中间层,我建议使用GNU的readline,就像前面提到的,或者RawLine库由H3RALD生活:

http://www.h3rald.com/rawline/
http://www.h3rald.com/articles/real-world-rawline-usage/

例使用termios的非缓冲输入:

require 'rubygems' 
require 'termios' 

def with_unbuffered_input 
    old_attrs = Termios.tcgetattr(STDOUT) 

    new_attrs = old_attrs.dup 

    new_attrs.lflag &= ~Termios::ECHO 
    new_attrs.lflag &= ~Termios::ICANON 

    Termios::tcsetattr(STDOUT, Termios::TCSANOW, new_attrs) 

    yield 
ensure 
    Termios::tcsetattr(STDOUT, Termios::TCSANOW, old_attrs) 
end 

with_unbuffered_input do 
    10.times { 
    c = STDIN.getc 
    puts "Got #{c}" 
    } 
end 
-1

从红宝石1.9.3开始,io/console随红宝石一起发货。可以使用其#raw实现无缓冲输入:

http://ruby-doc.org/stdlib-2.2.2/libdoc/io/console/rdoc/IO.html#method-i-raw

然而,箭头键由字符序列,而不是单个字符来表示。该序列始终始于"\e",但不幸的是没有任何序列结束标记。

像这样的东西可以用来读取方向键:

require 'io/console' 
require 'timeout' 

def readkey 
    c = '' 
    result = '' 
    $stdin.raw do |stdin| 
    c = stdin.getc 
    result << c 
    if c == "\e" 
     begin 
     while (c = Timeout::timeout(0.0001) { stdin.getc }) 
      result << c 
     end 
     rescue Timeout::Error 
     # no action required 
     end 
    end 
    end 
    result 
end 

puts readkey.inspect #=> outputs "\e[D" if left arrow is pressed