在Ruby控制台应用程序中获取键盘事件(没有按’enter’输入)的最佳方法是什么?

我一直在网上寻找这个答案一段时间,并发现其他人也在问同样的事情,即使在这里。 所以这篇文章将介绍我的案例,并回应我发现的“解决方案”。

我是Ruby的新手,但出于学习目的,我决定在这里创建一个gem。 我正在尝试对该程序实现键盘导航,这将允许用户使用快捷方式来选择他想要查看的请求类型。 在未来,箭头导航等

我的问题:我找不到一种通过Ruby从用户控制台获取键盘事件的一致方法。

我尝试过的解决方案:

  1. Highline gem:似乎不再支持此function。 无论如何它使用STDIN,继续阅读。
  2. STDIN.getch:我需要在并行循环中运行它,因为在用户可以使用快捷方式的同时,可以创建更多数据并且程序需要显示它。 好吧,我在控制台中显示格式化文本(Rails日志)。 当这个循环运行时,我的文本丢失了所有格式。
  3. 诅咒:很酷,但我需要设置位置(x,y)来每次显示我的文字? 会让人感到困惑。

这是我想要做的地方。 您可能会注意到我在显示我的文本之前使用“stty -raw echo”(关闭生成)并且之后使用“stty raw -echo”(生成开启)。 这使我的文本格式化。

但我的关键监听器循环不起作用。 我的意思是,它有时有效,但不一致。 如果按两次键,它就不再起作用,有时它也会单独停止。

我在这里放一部分代码:

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.getch没有问题。 我只是在显示任何字符串之前关闭原始模式。 一切都很好。

你可以在这里查看 ,或在gem本身。

而已。