我正在用Ruby写一个类似curses的程序,我正在使用stty和ansi转义字符来实现我想要的。当我想获得用户输入时,我的问题就出现了。像许多基于控制台的程序一样,我希望从终端的底部获得用户输入。
因此,我将光标放在屏幕的底部并调用Readline.readline(或任何方法来获取用户输入)。像往常一样,它会读取所有内容,直到我返回,并打印换行符。由于光标位于终端的最后一行,它会滚动一行,这会弄乱屏幕。
我该如何避免这种情况?我试图用stty来阻止新行的回应,但我没有成功。也许可以使用stty来阻止终端滚动?当然,我可以编写自己的方法来捕获输入,一次读取一个字符(并捕获“返回”),但我想使用readline提供的所有额外内容。
答案 0 :(得分:1)
Ruby Readline是GNU Readline库的一个简单包装器,它直接管理终端模式 - 这就是为什么使用stty修改终端设置可能没什么好运的原因。 Readline.readline方法专门将终端置于原始模式,并将所有字符回送到STDOUT(或者Ruby 1.9的Readline.output,默认为STDOUT)。
不幸的是,Ruby Readline包装器完全包装GNU Readline库; GNU Readline为redisplay提供了许多函数,但Ruby Readline包装器不公开这些函数。
如果您特别想使用Readline和Ruby并且需要忽略该换行符,那么您没有大量的选择。一个选项,有点愚蠢,是打开一个管道作为中介,监听自己的线程,并将所有Readline输出转发给它。以下是完成此操作,但请注意,这不是您真正想要的(并且在OSX上它需要ruby 1.9.2链接到readline而不是libedit,因为libedit阻塞了)....
require 'readline'
`mkfifo /tmp/readline-pipe`
Readline.output = File.open("/tmp/readline-pipe", "w+")
Thread.new {
input = open("/tmp/readline-pipe", "r+")
while true
character = input.getc
if character != "\n"
$stdout.write(character)
$stdout.flush
end
end
}
begin
while line = Readline.readline("", true)
$stdout.write(" NEWLINE ENTERED BUT NOT DISPLAYED ")
$stdout.flush
end
rescue EOFError
puts "Exiting..."
end