【问题标题】:How can I read a single character from STDIN in Clojure?如何在 Clojure 中从 STDIN 读取单个字符?
【发布时间】:2019-10-26 14:58:41
【问题描述】:

我正在编写一个仅适用于单字符输入的循环。根据用户按下的内容(不按 ENTER),我想显示用户输入的键,然后重复。如果用户按“q”,则循环必须退出。

约束:

  • 我不关心 Unicode(只支持 US ASCII 字符集是可取的)。
  • 我只关心 Unixy 系统(只有 Linux 可以)。
  • 我正在使用 Leiningen。

这可以吗?一些搜索使我找到了具有 ConsoleReader 类的 jline2,但它似乎在 jline3 中消失了。

【问题讨论】:

  • Clojure 问题,但我认为 Java 答案适用于此。
  • 非常感谢。我将使用 Clojure MWE 更新其他问题,然后单击“解决了我的问题!”按钮,可以吗?
  • 我不认为应该修改其他问题。如果它回答了您的问题,是的,您可以接受重复的建议。
  • 好吧,我在这里发布了一个答案,在 Clojure 中为我解决了这个问题。它可能会帮助其他 Clojurists。另一个问题确实有点帮助,但我仍然不得不根据另一个要点稍微调整一下。鉴于此,这个问题和答案可能具有足够的原创性,可以保持原样。我对我的解决方案很满意,所以可以随意调整。 耸耸肩

标签: terminal clojure console stdin tty


【解决方案1】:

我看到https://gist.github.com/mikeananev/f5138eeee12144a3ca82136184e7a742 并使用链接的重复答案,想出了这个:

; Need `(:import [org.jline.terminal TerminalBuilder Terminal])`

(defn new-terminal
  "creates new JLine3 Terminal.
  returns terminal object"
  ^Terminal [term-name]
  (let [terminal (-> (TerminalBuilder/builder)
                     (.jna true)
                     (.system true)
                     (.name term-name)
                     (.build))]
    terminal))

(defn interactive-loop []
  (let [t (new-terminal "xxx")]
    (.enterRawMode t)
    (let [reader (.reader t)]
    (loop [char-int (.read reader)]
      (case (char char-int)
        \q (do
          (println "Bye!")
          (.close reader)
          (.close t))
        (do (println (char char-int))
            (recur (.read reader))))))))

我在 NixOS 上,显然 jline3 库依赖于正在安装的 infocmp 二进制文件,它是流行的 ncurses 包的一部分。不幸的是,我目前使用的 Nixpkgs 版本没有打包这个二进制文件,所以我在这里放了一个 PR:https://github.com/NixOS/nixpkgs/pull/72135

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 2013-04-20
    • 1970-01-01
    相关资源
    最近更新 更多