首页 > 解决方案 > 如何在 Clojure 中从 STDIN 读取单个字符?

问题描述

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

约束:

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

标签: terminalclojureconsolestdintty

解决方案


我看到了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


推荐阅读