fix: replace stty size with tput cols/lines in backend-size
stty size returns incomplete data when run through uiop:run-program (the child may not have terminal access). tput is a terminfo utility that outputs a single number per call, avoiding parsing issues. Works reliably in any subprocess context.
This commit is contained in:
@@ -162,25 +162,21 @@ as a fallback when a keyword is not in *named-colors*.")
|
|||||||
(values))
|
(values))
|
||||||
|
|
||||||
(defmethod backend-size ((b modern-backend))
|
(defmethod backend-size ((b modern-backend))
|
||||||
(or ;; stty size via subprocess — most reliable across all systems.
|
(or ;; tput lines / tput cols via subprocess — most reliable across
|
||||||
;; Returns "ROWS COLS". stty size queries the terminal via ioctl,
|
;; all systems. Each outputs a single number. Works in any
|
||||||
;; not stdin, so no :input redirection is needed.
|
;; subprocess context, no parsing complexity.
|
||||||
(multiple-value-bind (cols rows)
|
(multiple-value-bind (cols rows)
|
||||||
(ignore-errors
|
(values
|
||||||
(let* ((out (uiop:run-program '("stty" "size")
|
(ignore-errors
|
||||||
:output :string
|
(parse-integer
|
||||||
:ignore-error-status t))
|
(string-trim '(#\newline #\space)
|
||||||
(parts (and out (uiop:split-string
|
(uiop:run-program '("tput" "cols") :output :string
|
||||||
(string-trim '(#\newline #\space) out)))))
|
:ignore-error-status t))))
|
||||||
(when parts
|
(ignore-errors
|
||||||
(let ((a (parse-integer (first parts) :junk-allowed t))
|
(parse-integer
|
||||||
(b (when (cdr parts) (parse-integer (second parts) :junk-allowed t))))
|
(string-trim '(#\newline #\space)
|
||||||
(if (and a b (> a 0) (> b 0))
|
(uiop:run-program '("tput" "lines") :output :string
|
||||||
;; stty returns "ROWS COLS"
|
:ignore-error-status t)))))
|
||||||
(values b a)
|
|
||||||
;; stty returned only one value — treat as cols
|
|
||||||
(when (and a (> a 0))
|
|
||||||
(values a nil)))))))
|
|
||||||
(when (and cols rows (> cols 0) (> rows 0))
|
(when (and cols rows (> cols 0) (> rows 0))
|
||||||
(values cols rows)))
|
(values cols rows)))
|
||||||
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
||||||
|
|||||||
@@ -22,21 +22,19 @@
|
|||||||
(values))
|
(values))
|
||||||
|
|
||||||
(defmethod backend-size ((b simple-backend))
|
(defmethod backend-size ((b simple-backend))
|
||||||
(or ;; stty size via subprocess — most reliable across all systems.
|
(or ;; tput cols / tput lines via subprocess
|
||||||
(multiple-value-bind (cols rows)
|
(multiple-value-bind (cols rows)
|
||||||
(ignore-errors
|
(values
|
||||||
(let* ((out (uiop:run-program '("stty" "size")
|
(ignore-errors
|
||||||
:output :string
|
(parse-integer
|
||||||
:ignore-error-status t))
|
(string-trim '(#\newline #\space)
|
||||||
(parts (and out (uiop:split-string
|
(uiop:run-program '("tput" "cols") :output :string
|
||||||
(string-trim '(#\newline #\space) out)))))
|
:ignore-error-status t))))
|
||||||
(when parts
|
(ignore-errors
|
||||||
(let ((a (parse-integer (first parts) :junk-allowed t))
|
(parse-integer
|
||||||
(b (when (cdr parts) (parse-integer (second parts) :junk-allowed t))))
|
(string-trim '(#\newline #\space)
|
||||||
(if (and a b (> a 0) (> b 0))
|
(uiop:run-program '("tput" "lines") :output :string
|
||||||
(values b a) ; stty returns "ROWS COLS"
|
:ignore-error-status t)))))
|
||||||
(when (and a (> a 0))
|
|
||||||
(values a nil)))))))
|
|
||||||
(when (and cols rows (> cols 0) (> rows 0))
|
(when (and cols rows (> cols 0) (> rows 0))
|
||||||
(values cols rows)))
|
(values cols rows)))
|
||||||
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
||||||
|
|||||||
Reference in New Issue
Block a user