fix: disable kitty keyboard, fix CSI parser crashes

- Disabled \033[?u kitty keyboard protocol in modern-backend
  (converts all keys to escape sequences, breaking Ctrl+letter dispatch)
- Fixed parse-csi-sequence: use multiple-value-bind instead of let*
  with destructuring-bind (lost secondary return value from read-param)
- Fixed parse-csi-params format string: pass char-code of terminator
  as distinct argument for ~d, keeping the character for ~C
- Added %query-terminal-size in classes.lisp: ANSI CSI 18t fallback
  for terminal size detection when ioctl fails or returns zero
This commit is contained in:
2026-05-14 09:31:09 -04:00
parent e8b37f6268
commit 14b41831c3
4 changed files with 50 additions and 14 deletions

View File

@@ -1,5 +1,36 @@
(in-package :cl-tty.backend)
(defun %query-terminal-size ()
"Query terminal size via ANSI CSI 18 t and parse the response.
Returns (values cols rows) or nil."
(ignore-errors
(let* ((saved (sb-sys:make-fd-stream 0 :input t :buffering :none))
(response (make-array 0 :element-type 'character
:fill-pointer 0 :adjustable t)))
(format t "~C[18t" #\Esc)
(force-output)
(loop with deadline = (+ (get-internal-real-time)
(* internal-time-units-per-second 0.2))
while (< (get-internal-real-time) deadline)
do (let ((ch (read-char-no-hang saved nil nil)))
(when ch
(vector-push-extend ch response)
(when (char= ch #\t) (return)))))
(when (>= (length response) 8)
(let* ((str (subseq response 1))
(start (or (position #\[ str) 0))
(after (subseq str (1+ start)))
(semi (position #\; after)))
(when semi
(let* ((cols-start (1+ semi))
(cols-end (position #\t after :start cols-start))
(rows (parse-integer (subseq after 0 semi) :junk-allowed t))
(cols (when cols-end
(parse-integer (subseq after cols-start cols-end)
:junk-allowed t))))
(when (and rows cols (> rows 0) (> cols 0))
(values cols rows)))))))))
(defclass backend () ())
(defgeneric initialize-backend (backend)