From 4fa7e98b807f003a725cf1c7e896bdfc91766e17 Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Thu, 14 May 2026 13:36:54 -0400 Subject: [PATCH] fix: set both dimensions from stty, add tput fallback, export shell vars - stty size returns 'rows cols'. Old code set only one dimension when both env vars were missing; new code sets both. - Added tput cols/lines as final env-var fallback for systems where COLUMNS/LINES are not exported and stty is unavailable. - Added 'export COLUMNS LINES' to the passepartout script so SBCL can read them from the environment. --- src/backend/modern.lisp | 22 +++++++++++++++++----- src/backend/simple.lisp | 19 +++++++++++++++---- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/backend/modern.lisp b/src/backend/modern.lisp index 7882778..20d8a3c 100644 --- a/src/backend/modern.lisp +++ b/src/backend/modern.lisp @@ -180,7 +180,7 @@ as a fallback when a keyword is not in *named-colors*.") (rstr (sb-ext:posix-getenv "LINES")) (cols (when cstr (parse-integer cstr :junk-allowed t))) (rows (when rstr (parse-integer rstr :junk-allowed t)))) - ;; If only one env var is set, get the other from stty + ;; If env vars are missing, use stty size (rows cols) (unless (and cols rows) (let* ((out (uiop:run-program '("stty" "size") :output :string @@ -188,10 +188,22 @@ as a fallback when a keyword is not in *named-colors*.") (parts (and out (uiop:split-string (string-trim '(#\newline #\space) out))))) (when (and parts (= (length parts) 2)) - (let ((a (parse-integer (first parts) :junk-allowed t)) - (b (parse-integer (second parts) :junk-allowed t))) - (when (and a b (> a 0) (> b 0)) - (if cols (setf rows b) (setf cols a))))))) + (let ((stty-rows (parse-integer (first parts) :junk-allowed t)) + (stty-cols (parse-integer (second parts) :junk-allowed t))) + (when (and stty-rows stty-cols (> stty-rows 0) (> stty-cols 0)) + (unless cols (setf cols stty-cols)) + (unless rows (setf rows stty-rows))))))) + ;; If still missing, try tput as final shell fallback + (unless (and cols rows) + (let ((out (uiop:run-program '("sh" "-c" "tput cols 2>/dev/null; tput lines 2>/dev/null") + :output :string + :ignore-error-status t))) + (when out + (let* ((parts (uiop:split-string (string-trim '(#\newline #\space) out))) + (a (when parts (parse-integer (first parts) :junk-allowed t))) + (b (when (cdr parts) (parse-integer (second parts) :junk-allowed t)))) + (when a (setf cols a)) + (when b (setf rows b)))))) (when (and cols rows (> cols 0) (> rows 0)) (values cols rows)))) (values 80 24))) diff --git a/src/backend/simple.lisp b/src/backend/simple.lisp index 79bff82..67738d0 100644 --- a/src/backend/simple.lisp +++ b/src/backend/simple.lisp @@ -46,10 +46,21 @@ (parts (and out (uiop:split-string (string-trim '(#\newline #\space) out))))) (when (and parts (= (length parts) 2)) - (let ((a (parse-integer (first parts) :junk-allowed t)) - (b (parse-integer (second parts) :junk-allowed t))) - (when (and a b (> a 0) (> b 0)) - (if cols (setf rows b) (setf cols a))))))) + (let ((stty-rows (parse-integer (first parts) :junk-allowed t)) + (stty-cols (parse-integer (second parts) :junk-allowed t))) + (when (and stty-rows stty-cols (> stty-rows 0) (> stty-cols 0)) + (unless cols (setf cols stty-cols)) + (unless rows (setf rows stty-rows))))))) + (unless (and cols rows) + (let ((out (uiop:run-program '("sh" "-c" "tput cols 2>/dev/null; tput lines 2>/dev/null") + :output :string + :ignore-error-status t))) + (when out + (let* ((parts (uiop:split-string (string-trim '(#\newline #\space) out))) + (a (when parts (parse-integer (first parts) :junk-allowed t))) + (b (when (cdr parts) (parse-integer (second parts) :junk-allowed t)))) + (when a (setf cols a)) + (when b (setf rows b)))))) (when (and cols rows (> cols 0) (> rows 0)) (values cols rows)))) (values 80 24)))