Как запустить интерактивную программу CLI из Clojure? - PullRequest
2 голосов
/ 11 июня 2019

Я бы хотел запустить интерактивную программу CLI из Clojure (например, vim) и иметь возможность взаимодействовать с ней.

В bash и других языках программирования я могу сделать это с помощью

vim > `tty`

Я пытался сделать то же самое в Clojure:

(require '[clojure.java.shell :as shell])
(shell/sh "vim > `tty`")

, но он просто открывает vim, не давая мне tty.


Справочная информация: я разрабатываюИнструмент CLI Clojure, который анализирует электронные письма и позволяет пользователю редактировать проанализированные данные перед сохранением их на диск.Он работает следующим образом:

  1. Считайте файл с содержимым электронной почты и проанализируйте его.Каждое письмо хранится в отдельном файле.
  2. Показывает пользователю проанализированные данные и позволяет пользователю редактировать данные в vim.Внутренне я создаю временный файл с проанализированными данными, но я не против сделать это по-другому, если это решит мою проблему.
  3. После того, как пользователь закончит редактирование проанализированных данных (они могут решить сохранить его какэто) добавить данные в файл на диске.Таким образом, все проанализированные данные сохраняются в одном файле.
  4. Перейдите к 1-му шагу, если остались какие-либо файлы с оставленными электронными письмами.

1 Ответ

0 голосов
/ 10 июля 2019

Этот код опирается на взаимодействие Clojure Java для использования класса ProcessBuilder Java.

(defn -main
[]
;use doseq instead of for because for is lazily evaluated
(doseq [i [1 2 3]]
;extract current directory from system variable
(let [file-name (str "test" i ".txt")
      working-directory (trim-newline (:out (sh "printenv" "PWD")))]
  (spit file-name "")

  ;this is where fun begins. We use ProcessBuilder to forward commands to terminal
  ;we pass a list of commands and their arguments to its constructor
  (let [process-builder (java.lang.ProcessBuilder. (list "vim" (str working-directory "/" file-name)))
  ;inherit is a configuration constant
        inherit (java.lang.ProcessBuilder$Redirect/INHERIT)]
  ;we configure input, output and error redirection
  (.redirectOutput process-builder inherit)
  (.redirectError process-builder inherit)
  (.redirectInput process-builder inherit)

  ;waitFor used to block execution until vim is closed
  (.waitFor (.start process-builder))
  )
  ;additional processing here
)
)
;not necessary but script tends to hang for around 30 seconds at end of its execution
;so this command is used to terminate it instantly
(System/exit 0)
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...