fix: move stty size to first priority in backend-size
stty size via subprocess is the most reliable method — it returns the correct 59x83 from the user's terminal. Move it before ioctl to ensure it's tried first.
This commit is contained in:
@@ -162,21 +162,9 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(values))
|
||||
|
||||
(defmethod backend-size ((b modern-backend))
|
||||
(or (ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(sb-unix:unix-ioctl (sb-sys:fd-stream-fd (backend-output-stream b))
|
||||
+tiocgwinsz+
|
||||
(sb-alien:alien-sap winsize))
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
;; stty size via subprocess — reliable on every Unix, bypasses
|
||||
;; SBCL's alien/ioctl quirks. Returns "ROWS COLS". Use sh -c
|
||||
;; with explicit /dev/tty to ensure stty sees the real terminal
|
||||
;; (uiop:run-program may redirect stdin).
|
||||
(or ;; stty size via subprocess — most reliable across all systems.
|
||||
;; Returns "ROWS COLS". Uses explicit /dev/tty to bypass any
|
||||
;; stdin redirection from uiop:run-program.
|
||||
(ignore-errors
|
||||
(let* ((out (uiop:run-program '("sh" "-c" "stty size < /dev/tty")
|
||||
:output :string
|
||||
@@ -188,6 +176,18 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(cols (parse-integer (second parts) :junk-allowed t)))
|
||||
(when (and rows cols (> rows 0) (> cols 0))
|
||||
(values cols rows))))))
|
||||
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
||||
(ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(sb-unix:unix-ioctl (sb-sys:fd-stream-fd (backend-output-stream b))
|
||||
+tiocgwinsz+
|
||||
(sb-alien:alien-sap winsize))
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
;; Direct ioctl on /dev/tty — opens the real controlling terminal.
|
||||
(ignore-errors
|
||||
(let ((tty-fd (sb-unix:unix-open "/dev/tty" 0 0))) ; O_RDONLY
|
||||
|
||||
@@ -22,7 +22,19 @@
|
||||
(values))
|
||||
|
||||
(defmethod backend-size ((b simple-backend))
|
||||
(or (ignore-errors
|
||||
(or ;; stty size via subprocess — most reliable across all systems.
|
||||
(ignore-errors
|
||||
(let* ((out (uiop:run-program '("sh" "-c" "stty size < /dev/tty")
|
||||
:output :string
|
||||
:ignore-error-status t))
|
||||
(parts (and out (uiop:split-string
|
||||
(string-trim '(#\newline #\space) out)))))
|
||||
(when (and parts (= (length parts) 2))
|
||||
(let ((rows (parse-integer (first parts) :junk-allowed t))
|
||||
(cols (parse-integer (second parts) :junk-allowed t)))
|
||||
(when (and rows cols (> rows 0) (> cols 0))
|
||||
(values cols rows))))))
|
||||
(ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523)
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
|
||||
Reference in New Issue
Block a user