某些Clojure函数(例如defrecord
)的文档字符串很长。在终端窗口中运行Clojure时,我希望能够通过doc
(或more
)之类的寻呼机实际发送less
的输出。如果有人在Clojure中编写了一个寻呼机功能,那么我想我可以将它与以下内容一起使用:
(with-out-str (doc defrecord))
或者如果有一个标准的Java类实现了一个寻呼机,我可以弄清楚如何将输出发送给它。
或者,如何将doc
的输出发送到shell命令?这不起作用:
(clojure.java.shell/sh "more" :in (with-out-str (doc defrecord))))
[这个主题难以搜索:“更多”,“更少”和“doc”显然是非常常见的术语,像“java pager”这样的内容会提出讨论如何将文本分解为格式化文档的页面的页面]
答案 0 :(得分:2)
您可以使用jline。如果您使用setPaginationEnabled
拨打true
并使用printColumns
方法,则会在您的jline ConsoleReader
上进行寻呼。
但是,如果你想在标准的Leiningen REPL上做这件事,情况会变得更复杂。 Leiningen v2的当前版本使用REPL-y,它在内部使用jline,但不使用printColumns
,因此忽略jline分页。
然而,您可以通过REPL-y的ConsoleReader在reply.reader.simple-jline/jline-state
中获取当前的Leiningen REPL高度,并使用它来对文档字符串进行分区。
(defmacro doc2 [x]
`(let [h# (-> @reply.reader.simple-jline/jline-state :reader (.. getTerminal getHeight) (- 4))
[s1# s2#] (split-at h# (-> ~x clojure.repl/doc with-out-str clojure.string/split-lines))]
(doseq [x# s1#] (println x#))
(doseq [i# (partition-all h# s2#)]
(println "\n<more>")
(read-line)
(doseq [x# i#] (println x#)))))
您可能希望将此宏放在profiles.clj
个人资料下的:repl
。
{:user {:plugins [...]}
:repl {:repl-options {:init (defmacro doc2 [x] ...)}}}
这会在您加载repl时将doc2
宏放在user
命名空间中。
答案 1 :(得分:1)
echo "(doc defrecord)" |clj|more