fix: cat buffering, dialog filter int-chars, remove double render

- Wrap cat with stdbuf -o0 so keystrokes aren't stuck in cat's 4096-byte
  pipe buffer — text input was invisible until buffer filled
- Dialog filter: (characterp ch) rejects integer char codes from raw event
  dispatch. Accept integerp in range 32-126 and convert via code-char
- Remove initial render (backend-clear + view calls) before main loop.
  Dirty flags already trigger a full sync-wrapped redraw in the first
  iteration, eliminating the pre-loop clear flash
This commit is contained in:
2026-05-14 20:29:50 -04:00
parent 25da9ae685
commit 3661d00138

View File

@@ -907,7 +907,7 @@ supplied (e.g. \"/\"), pre-fill the select filter with it."
;; A cat subprocess reads keyboard input from the terminal. ;; A cat subprocess reads keyboard input from the terminal.
;; Global vars for cat subprocess — avoid lexical let* scope issue ;; Global vars for cat subprocess — avoid lexical let* scope issue
(progn (progn
(setq *cat-proc* (uiop:launch-program '("cat") (setq *cat-proc* (uiop:launch-program '("stdbuf" "-o0" "cat")
:output :stream :output :stream
:input :interactive :input :interactive
:stderr nil) :stderr nil)
@@ -920,17 +920,9 @@ supplied (e.g. \"/\"), pre-fill the select filter with it."
(let ((backend-type (if (typep be 'cl-tty.backend:modern-backend) (let ((backend-type (if (typep be 'cl-tty.backend:modern-backend)
"modern" "simple"))) "modern" "simple")))
(add-msg :system (format nil "* ~a backend ~dx~d *" backend-type w h))) (add-msg :system (format nil "* ~a backend ~dx~d *" backend-type w h)))
;; Guard against nil w/h from backend-size ;; Initial dirty all to trigger first redraw in loop
(setq w (or (and (numberp w) (> w 0) w) 80) (setq w (or (and (numberp w) (> w 0) w) 80)
h (or (and (numberp h) (> h 0) h) 24)) h (or (and (numberp h) (> h 0) h) 24))
;; Log backend info and terminal dimensions
(cl-tty.backend:backend-clear be)
(view-status be w h)
(view-chat be w h)
;; Draw separator line above input
(cl-tty.backend:draw-text be 0 (- h 4) (make-string w :initial-element #\─)
(theme-color :separator) nil)
(view-input be w h)
(loop while (st :running) do (loop while (st :running) do
(dolist (ev (drain-queue)) (dolist (ev (drain-queue))
(cond (cond
@@ -968,11 +960,14 @@ supplied (e.g. \"/\"), pre-fill the select filter with it."
(when item (when item
(let ((cb (cl-tty.select:select-on-select sel))) (let ((cb (cl-tty.select:select-on-select sel)))
(when cb (funcall cb item)))))) (when cb (funcall cb item))))))
((and (characterp ch) (graphic-char-p ch)) ((let ((chr (if (characterp ch) ch
(setf (cl-tty.select:select-filter sel) (and (integerp ch) (<= 32 ch 126)
(concatenate 'string (code-char ch)))))
(or (cl-tty.select:select-filter sel) "") (and chr (graphic-char-p chr))
(string ch)))) (setf (cl-tty.select:select-filter sel)
(concatenate 'string
(or (cl-tty.select:select-filter sel) "")
(string chr)))))
((member ch '(:backspace 127 8)) ((member ch '(:backspace 127 8))
(let ((f (cl-tty.select:select-filter sel))) (let ((f (cl-tty.select:select-filter sel)))
(when (> (length f) 0) (when (> (length f) 0)