在 Ruby 控制台应用程序中获取键盘事件(无需按"输入"即可输入)的最佳方法是什么?



我在网上寻找这个答案已经有一段时间了,并且发现其他人也在问同样的问题,甚至在这里。所以这篇文章将展示我的案例,并对我找到的"解决方案"做出回应。

我是Ruby的新手,但出于学习的目的,我决定在这里创建一个gem。我试图实现一个键盘导航到这个程序,这将允许用户使用快捷键来选择他想要看到什么样的请求。在未来,箭头导航等

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

我尝试过的解决方案:

  1. Highline gem:似乎不支持这个功能了。无论如何,它使用STDIN,继续阅读。
  2. STDIN。getch:我需要在并行循环中运行它,因为在用户可以使用快捷方式的同时,可以创建更多的数据,并且程序需要显示它。我在控制台中显示格式化的文本(Rails日志)。当这个循环运行时,我的文本失去了所有的格式。
  3. 诅咒:酷,但我需要设置位置(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中查看。

最新更新