(ns tui.terminal "Terminal management: raw mode, size, input/output." (:require [tui.ansi :as ansi] [clojure.java.io :as io]) (:import [java.io BufferedReader InputStreamReader])) ;; === Terminal State === (def ^:private original-stty (atom nil)) (defn- stty [& args] (let [cmd (concat ["sh" "-c" (str "stty " (clojure.string/join " " args) " = c 0) (char c))))) (defn read-available "Read all available characters without blocking." [] (when-let [r @tty-reader] (loop [chars []] (if (.ready r) (let [c (.read r)] (if (>= c 0) (recur (conj chars (char c))) chars)) chars)))) (defn read-char-timeout "Read char with timeout in ms. Returns nil on timeout." [timeout-ms] (when-let [r @tty-reader] (let [deadline (+ (System/currentTimeMillis) timeout-ms)] (loop [] (cond (.ready r) (let [c (.read r)] (when (>= c 0) (char c))) (> (System/currentTimeMillis) deadline) nil :else (do (Thread/sleep 1) (recur)))))))