fix: use global vars for cat subprocess to avoid let* scope crash
Replaced (let* ((cat-proc ...) (tty-in ...)) ...) with global special variables *cat-proc* and *tty-in* with defvar declarations. The let* caused 'unbound variable' errors on Ctrl+Q because the lexical scope didn't extend to terminate-process. Global vars have indefinite scope and work reliably regardless of paren nesting.
This commit is contained in:
@@ -886,6 +886,9 @@ Event handlers + daemon I/O + main loop.
|
||||
(:down (lambda (e) (declare (ignore e)) (on-key :down)))
|
||||
(:escape (lambda (e) (declare (ignore e)) (on-key :escape)))))
|
||||
|
||||
(defvar *cat-proc* nil "Cat subprocess for keyboard input")
|
||||
(defvar *tty-in* nil "Stream from cat subprocess stdout")
|
||||
|
||||
(defun tui-main ()
|
||||
(init-state)
|
||||
(load-history)
|
||||
@@ -912,12 +915,14 @@ Event handlers + daemon I/O + main loop.
|
||||
;; bytes through a pipe that SBCL reads reliably.
|
||||
;; stty -icanon -echo is set by the bash script before exec sbcl.
|
||||
;; A cat subprocess reads keyboard input from the terminal.
|
||||
(let* ((cat-proc (uiop:launch-program '("cat")
|
||||
;; Global vars for cat subprocess — avoid lexical let* scope issue
|
||||
(progn
|
||||
(setq *cat-proc* (uiop:launch-program '("cat")
|
||||
:output :stream
|
||||
:input :interactive
|
||||
:stderr nil))
|
||||
(tty-in (uiop:process-info-output cat-proc)))
|
||||
(add-msg :system (format nil "* cat pid=~a *" (uiop:process-info-pid cat-proc)))
|
||||
:stderr nil)
|
||||
*tty-in* (uiop:process-info-output *cat-proc*)))
|
||||
(add-msg :system (format nil "* cat pid=~a *" (uiop:process-info-pid *cat-proc*)))
|
||||
;; Guard against nil w/h from backend-size
|
||||
(setq w (or (and (numberp w) (> w 0) w) 80)
|
||||
h (or (and (numberp h) (> h 0) h) 24))
|
||||
@@ -990,7 +995,7 @@ Event handlers + daemon I/O + main loop.
|
||||
;; Keyboard reader: block on cat pipe with 0.1s timeout.
|
||||
(handler-case
|
||||
(sb-ext:with-timeout 0.1
|
||||
(let ((raw-ch (read-char tty-in nil nil)))
|
||||
(let ((raw-ch (read-char *tty-in* nil nil)))
|
||||
(when raw-ch
|
||||
(let ((code (char-code raw-ch)))
|
||||
(queue-event
|
||||
@@ -1064,12 +1069,12 @@ Event handlers + daemon I/O + main loop.
|
||||
(cond (cat (theme-color :dim))
|
||||
(sel-p (theme-color :accent))
|
||||
(t (theme-color :agent-fg)))
|
||||
nil :bold sel-p)
|
||||
(incf y-off)))))))
|
||||
nil :bold sel-p)
|
||||
(incf y-off)))))))
|
||||
(sleep 0.1))
|
||||
(uiop:terminate-process cat-proc))
|
||||
(add-msg :system (format nil "* cat ~a ended *" (uiop:process-info-pid cat-proc))))
|
||||
(progn (disconnect-daemon))))
|
||||
(uiop:terminate-process *cat-proc*))
|
||||
(add-msg :system (format nil "* cat ~a ended *" (uiop:process-info-pid *cat-proc*))))
|
||||
(progn (disconnect-daemon)))
|
||||
#+END_SRC
|
||||
|
||||
* Test Suite
|
||||
|
||||
Reference in New Issue
Block a user