Skip to content

Commit

Permalink
Mechanism to caputure stdout and stderr from other processes
Browse files Browse the repository at this point in the history
  • Loading branch information
mogenslund committed Jun 1, 2021
1 parent 4fa95fe commit 0ede62b
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 39 deletions.
23 changes: 12 additions & 11 deletions src/liq/commands.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@

(defn external-command
[text]
#?(:clj (let [f (or ((editor/current-buffer) ::buffer/filename "."))
folder (or ((editor/current-buffer) :liq.modes.dired-mode/folder)
(util/absolute (util/get-folder f)))
#?(:clj (let [f (or (editor/current-file) ".")
folder (editor/current-folder)
text1 (str/replace text #"%" f)]
(editor/message (str "Running command: " text1 "\n") :view true)
(future
Expand Down Expand Up @@ -286,14 +285,16 @@
(defn output-snapshot
[]
(let [id (editor/get-buffer-id-by-name "output-snapshot")]
(if id
(editor/switch-to-buffer id)
(editor/new-buffer "" {:name "output-snapshot"}))
(editor/apply-to-buffer
#(-> %
buffer/clear
(buffer/insert-string
(buffer/text (editor/get-buffer "*output*")))))))
(if (= id (editor/current-buffer-id))
(editor/previous-buffer)
(do (if id
(editor/switch-to-buffer id)
(editor/new-buffer "" {:name "output-snapshot"}))
(editor/apply-to-buffer
#(-> %
buffer/clear
(buffer/insert-string
(buffer/text (editor/get-buffer "*output*")))))))))

(defn yank-inner-word
[]
Expand Down
5 changes: 4 additions & 1 deletion src/liq/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
(swap! editor/state assoc-in [:liq.editor/commands :fm]
(fn [] (editor/apply-to-buffer #(update % ::buffer/major-modes conj :freemove-mode)))))


;; clj -m liq.experiments.core
(defn -main
[& args]
Expand Down Expand Up @@ -123,7 +124,9 @@
(editor/set-output-handler output/output-handler)
(input/init)
(editor/set-exit-handler input/exit-handler)
(input/input-handler editor/handle-input)))
(input/input-handler editor/handle-input)
(input/redirect-stdout editor/handle-stdout)
(input/redirect-stderr editor/handle-stderr)))
(when (read-arg args "--notepad") (notepad-mode/load-notepad-mode))
(let [w (editor/get-window)
rows (w ::buffer/rows)
Expand Down
16 changes: 15 additions & 1 deletion src/liq/editor.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
:default-tabwidth 8}
::exit-handler nil
::window nil
::stdout ""
::stderr ""
::output-handler nil}))

(def ^:private macro-seq (atom ())) ; Macrofunctionality might belong to input handler.
Expand Down Expand Up @@ -125,7 +127,8 @@
(defn current-folder
[]
(let [f (or ((current-buffer) ::buffer/filename) ".")]
(util/absolute (util/get-folder f))))
(or ((current-buffer) :liq.modes.dired-mode/folder)
(util/absolute (util/get-folder f)))))

(defn switch-to-buffer
[idname]
Expand Down Expand Up @@ -286,6 +289,16 @@
(when timer (future (Thread/sleep timer) (previous-buffer) (paint-buffer))))
(paint-buffer))

(defn handle-stdout
[s]
(swap! state update ::stdout str s)
(message s :append true))

(defn handle-stderr
[s]
(swap! state update ::stderr str s)
(message s :append true))

(defn force-kill-buffer
([idname]
(when (not= idname "scratch")
Expand Down Expand Up @@ -440,3 +453,4 @@
[]
(when (not @macro-record)
(doall (map handle-input (reverse @macro-seq)))))

21 changes: 19 additions & 2 deletions src/liq/tty_input.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
[clojure.java.io :as io]
[clojure.java.shell :as shell]
[liq.util :as util]
[liq.tty-shared :as shared]))
[liq.tty-shared :as shared])
(:import [java.io PrintStream FileOutputStream FileDescriptor]
[java.io ByteArrayOutputStream BufferedReader]))

(def esc "\033[")
(def ^:private sysout (System/out))
Expand All @@ -27,6 +29,7 @@

(defn exit-handler
[]
(PrintStream. (FileOutputStream. (FileDescriptor/out)))
(shared/tty-print "\033[0;37m\033[2J")
(shared/tty-print "\033[?25h")
(shell/sh "/bin/sh" "-c" "stty -echo cooked </dev/tty")
Expand All @@ -39,12 +42,26 @@
(shared/tty-print esc "0;0H" esc "s")
(set-raw-mode))

(defn redirect-stdout
[fun]
(System/setOut
(PrintStream.
(proxy [ByteArrayOutputStream] []
(write [& b] (fun (if (= (count b) 1) (str (char (first b))) (str/join "" (map char (first b))))))))))

(defn redirect-stderr
[fun]
(System/setErr
(PrintStream.
(proxy [ByteArrayOutputStream] []
(write [& b] (fun (if (= (count b) 1) (str (char (first b))) (str/join "" (map char (first b))))))))))

(defn input-handler
[fun]
;(tty-print esc "0;37m" esc "2J")
(shared/tty-print esc "0;0H" esc "s")
(future
(let [r (java.io.BufferedReader. *in*)
(let [r (BufferedReader. *in*)
read-input (fn [] (shared/raw2keyword
(let [input0 (.read r)]
(if (= input0 27)
Expand Down
33 changes: 11 additions & 22 deletions src/liq/tty_output.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
(:require [liq.buffer :as buffer]
#?(:clj [clojure.java.io :as io])
#?(:clj [clojure.java.shell :as shell])
[liq.tty-shared :as shared]
; :cljs [lumo.io :as io]

[clojure.string :as str]))
Expand All @@ -11,25 +12,13 @@
(def ^:private last-buffer (atom nil))
(def esc "\033[")

(defn- tty-print
[& args]
#?(:bb (binding [*out* (io/writer System/out)] (print (str/join "" args)))
:clj (.print (System/out) (str/join "" args))
:cljs (js/process.stdout.write (str/join "" args))))

(defn- tty-println
[& args]
#?(:bb (binding [*out* (io/writer System/out)] (println (str/join "" args)))
:clj (.println (System/out) (str/join "" args))
:cljs (js/process.stdout.write (str (str/join "" args) "\n"))))

(defn rows
[]
#?(:clj (loop [shellinfo ((shell/sh "/bin/sh" "-c" "stty size </dev/tty") :out) n 0]
(if (or (re-find #"^\d+" shellinfo) (> n 10))
(Integer/parseInt (re-find #"^\d+" shellinfo))
(do
(tty-println n)
(shared/tty-println n)
(Thread/sleep 100)
(recur ((shell/sh "/bin/sh" "-c" "stty size </dev/tty") :out) (inc n)))))
:cljs (or 40 (aget (js/process.stdout.getWindowSize) 0))))
Expand All @@ -40,7 +29,7 @@
(if (or (re-find #"\d+$" shellinfo) (> n 10))
(dec (Integer/parseInt (re-find #"\d+$" shellinfo)))
(do
(tty-println n)
(shared/tty-println n)
(Thread/sleep 100)
(recur ((shell/sh "/bin/sh" "-c" "stty size </dev/tty") :out) (inc n)))))
:cljs (or 120 (aget (js/process.stdout.getWindowSize) 0))))
Expand Down Expand Up @@ -75,14 +64,14 @@
(reset! countdown-cache 9))
(when (> @countdown-cache 0)
(swap! countdown-cache dec)
(tty-print esc color "m")
(tty-print esc bgcolor "m")
(tty-print esc row ";" col "H" esc "s" ch)
(shared/tty-print esc color "m")
(shared/tty-print esc bgcolor "m")
(shared/tty-print esc row ";" col "H" esc "s" ch)
(swap! char-cache assoc k footprint))))

(defn invalidate-cache
[]
(tty-print esc "2J")
(shared/tty-print esc "2J")
(reset! char-cache {}))

(defn double-width?
Expand All @@ -107,8 +96,8 @@
crow (-> buf ::buffer/cursor ::buffer/row) ; Cursor row
ccol (-> buf ::buffer/cursor ::buffer/col)] ; Cursor col
(when (and (@settings ::cursor-draw-hack) (= cache-id @last-buffer))
(tty-print "")) ; To make it look like the cursor is still there while drawing.
(tty-print esc "?25l") ; Hide cursor
(shared/tty-print "")) ; To make it look like the cursor is still there while drawing.
(shared/tty-print esc "?25l") ; Hide cursor
(when-let [statusline (and (not= (buf ::buffer/name) "*minibuffer*") (buf :status-line))]
(print-buffer statusline))
;; Looping over the rows and cols in buffer window in the terminal
Expand Down Expand Up @@ -155,9 +144,9 @@
(doseq [co (range left (+ left cols))]
(draw-char c (+ top rows) co "38;5;11" "49")))
(when (buf :status-line)
(tty-print esc ccolor "m" esc cursor-row ";" cursor-col "H" esc "s" (or (and (not= (buffer/get-char buf) \tab) (buffer/get-char buf)) \space))
(shared/tty-print esc ccolor "m" esc cursor-row ";" cursor-col "H" esc "s" (or (and (not= (buffer/get-char buf) \tab) (buffer/get-char buf)) \space))
;(draw-char (or (and (not= (buffer/get-char buf) \tab) (buffer/get-char buf)) \space) cursor-row cursor-col ccolor "49")
(tty-print esc "?25h" esc cursor-row ";" cursor-col "H" esc "s")
(shared/tty-print esc "?25h" esc cursor-row ";" cursor-col "H" esc "s")
(reset! last-buffer cache-id)))))))

(def ^:private updater (atom nil))
Expand Down
6 changes: 4 additions & 2 deletions src/liq/tty_shared.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
(:require [clojure.string :as str]
#?(:clj [clojure.java.io :as io])))

#?(:clj (do (def out0 (java.io.PrintStream. (java.io.FileOutputStream. (java.io.FileDescriptor/out))))))

(defn tty-print
[& args]
#?(:bb (binding [*out* (io/writer System/out)] (print (str/join "" args)))
:clj (.print (System/out) (str/join "" args))
:clj (.print out0 (str/join "" args))
:cljs (js/process.stdout.write (str/join "" args))))

(defn tty-println
[& args]
#?(:bb (binding [*out* (io/writer System/out)] (println (str/join "" args)))
:clj (.println (System/out) (str/join "" args))
:clj (.println out0 (str/join "" args))
:cljs (js/process.stdout.write (str (str/join "" args) "\n"))))

(defn raw2keyword
Expand Down

0 comments on commit 0ede62b

Please sign in to comment.