2

我在互联网上寻找这个答案已经有一段时间了,发现其他人也在问同样的问题,即使在这里。所以这篇文章将是我的案例的介绍和对我找到的“解决方案”的回应。

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

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

我尝试过的解决方案:

  1. Highline gem:似乎不再支持此功能。无论如何它使用标准输入,继续阅读。
  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

我的路上需要一盏灯,我该怎么办?

4

1 回答 1

0

那是我的错误。这只是在另一个线程中运行的另一部分代码中的逻辑错误,因此 ruby​​ 默认情况下不显示错误。我使用了 ruby​​ -d 并意识到出了什么问题。这个错误弄乱了我的键盘输入。

所以现在它已经修复了,我正在使用 STDIN.getch 没有问题。我只是在显示任何字符串之前关闭原始模式。一切都很好。

您可以在此处查看,也可以在gem中查看。

而已。

于 2013-05-15T03:36:58.113 回答