Как я могу получить функции readline/rlwrap при использовании clojure.main/repl?

Как я могу получить функции readline-like (или rlwrap-like) из моего REPL, когда я использую функцию repl из clojure.main?

В основе этого лежит то, что я использую и настраиваю функцию break из The Joy of Clojure, First Edition. Я использую его изнутри lein repl REPL. Когда моя "точка останова" срабатывает, функциональность Leiningen REPL, подобная readline, исчезла, что является неудобным. Моя мышечная память заставляет меня ударить , а затем быстро Enter. Прежде чем я смогу остановиться, у меня есть это в моем терминале:

debug=> ^[[A
CompilerException java.lang.RuntimeException: Unable to resolve symbol: in this context, compiling:(/tmp/form-init13211381000659590518.clj:1:1) 

И теперь мой REPL застрял, и мне нужно убить терминал или процесс, чтобы выйти. Я бы очень хотел, если бы я мог либо читать readline, работающий в REPL второго уровня, либо, по крайней мере, предотвращать эту общую проблему от смены моих сеансов отладки.

Ответ 1

Вы должны использовать readline readel, новую замену clojure, разработанную bhauman, тем же парнем, который привел это figwheel.

https://github.com/bhauman/rebel-readline

Он имеет функции rlwrap, подсветку синтаксиса и редактирование многострочного кода в терминале.

Ответ 2

Я не уверен, что утилита rlwrap поможет там, потому что внутренний REPL удерживается внешним. Таким образом, ввод управляется кодом Java, а не инструментом rlwrap.

Вы вызываете исключение, так как вы вводите неправильное значение. Я помню, clojure.main/repl могла бы принять дополнительный аргумент для обработки исключений. Вероятно, вы могли бы как-то справиться с этим и просто напечатать строку "неправильное входное значение". Взгляните на документацию для REPL.

Кроме того, вы можете реализовать свой собственный REPL для отладки. Давным-давно я писал что-то вроде этого, вот что у меня есть:

(defn repl []
  (let [input (read)]
    (if (= input 'q)
      nil
      (do
        (try
          (let [result (eval input)]
            (println result))
          (catch Exception e
            (println e)))
        (recur)))))

Эта функция просто запрашивает правильное выражение Clojure в бесконечном цикле, оценивает его и печатает результат. В случае неправильного ввода, он печатает ошибку и продолжается. Чтобы оставить REPL, введите q.

Пример:

(repl)
(+ 1 2) ;; 2
fsdf8 9_fsd ;; prints a stack trace
q ;; returns nil and exit

Ответ 3

Попробуйте Emacs с сидром как ваш repl. Когда вы (break) вы столкнетесь с репликой Сидра и в Emacs Minibuffer, где продолжают применяться стандартные ярлыки редактирования emacs (на которых моделируется readline).