我在网上寻找这个答案已经有一段时间了,并且发现其他人也在问同样的问题,甚至在这里。所以这篇文章将展示我的案例,并对我找到的"解决方案"做出回应。
我是Ruby的新手,但出于学习的目的,我决定在这里创建一个gem。我试图实现一个键盘导航到这个程序,这将允许用户使用快捷键来选择他想要看到什么样的请求。在未来,箭头导航等
我的问题是:我找不到一个用Ruby从用户控制台获取键盘事件的一致方法。
我尝试过的解决方案:
- Highline gem:似乎不支持这个功能了。无论如何,它使用STDIN,继续阅读。
- STDIN。getch:我需要在并行循环中运行它,因为在用户可以使用快捷方式的同时,可以创建更多的数据,并且程序需要显示它。我在控制台中显示格式化的文本(Rails日志)。当这个循环运行时,我的文本失去了所有的格式。
- 诅咒:酷,但我需要设置位置(x,y)来显示我的文本每次?这会让人很困惑。
这就是我要做的。您可能会注意到,我在显示文本之前使用"stty -raw echo"(关闭raw),在显示文本之后使用"stty raw -echo"(打开raw)。这使我的文本格式。
但是我的关键监听器循环不起作用。我的意思是,它有时有效,但不是始终如一的。如果按两次键,它就不再工作了,有时它也会自动停止。
让我把一部分代码放在这里:
def run
# Two loops run in parallel using Threads.
# stream_log loops like a normal stream in the file, but it also parser the text.
# break it into requests and store in @requests_queue.
# stream_parsed_log stream inside the @requests_queue and shows it in the screen.
@requests_queue = Queue.new
@all_requests = Array.new
# It's not working yet.
Thread.new { listen_keyboard }
Thread.new { stream_log }
stream_parsed_log
end
def listen_keyboard
# not finished
loop do
char = STDIN.getch
case char
when 'q'
puts "Exiting."
exit
when 'a'
@types_to_show = ['GET', 'POST', 'PUT', 'DELETE', 'ASSET']
requests_to_show = filter_to_show(@all_requests)
command = true
when 'p'
@types_to_show = ['POST']
requests_to_show = filter_to_show(@all_requests)
command = true
end
clear_screen if command
@requests_queue += requests_to_show if command
command = false
end
end
我的路上需要一盏灯,我该怎么办?
那是我的错。这只是在另一个线程中运行的另一部分代码中的逻辑错误,所以ruby默认不会显示错误。我使用ruby -d并意识到哪里出了问题。这个错误弄乱了我的键盘输入。
所以现在它是固定的,我正在使用STDIN。盖奇,没问题。我只是在显示任何字符串之前关闭原始模式。一切都好。
你可以在这里查看,或者在gem中查看。
。