From 3661d0013829c04fdac816d206bd065adef7f19a Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Thu, 14 May 2026 20:29:50 -0400 Subject: [PATCH] fix: cat buffering, dialog filter int-chars, remove double render MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- org/channel-tui-main.org | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/org/channel-tui-main.org b/org/channel-tui-main.org index 8709dbb..3502b4f 100644 --- a/org/channel-tui-main.org +++ b/org/channel-tui-main.org @@ -907,7 +907,7 @@ supplied (e.g. \"/\"), pre-fill the select filter with it." ;; A cat subprocess reads keyboard input from the terminal. ;; Global vars for cat subprocess — avoid lexical let* scope issue (progn - (setq *cat-proc* (uiop:launch-program '("cat") + (setq *cat-proc* (uiop:launch-program '("stdbuf" "-o0" "cat") :output :stream :input :interactive :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) "modern" "simple"))) (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) 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 (dolist (ev (drain-queue)) (cond @@ -968,11 +960,14 @@ supplied (e.g. \"/\"), pre-fill the select filter with it." (when item (let ((cb (cl-tty.select:select-on-select sel))) (when cb (funcall cb item)))))) - ((and (characterp ch) (graphic-char-p ch)) - (setf (cl-tty.select:select-filter sel) - (concatenate 'string - (or (cl-tty.select:select-filter sel) "") - (string ch)))) + ((let ((chr (if (characterp ch) ch + (and (integerp ch) (<= 32 ch 126) + (code-char ch))))) + (and chr (graphic-char-p chr)) + (setf (cl-tty.select:select-filter sel) + (concatenate 'string + (or (cl-tty.select:select-filter sel) "") + (string chr))))) ((member ch '(:backspace 127 8)) (let ((f (cl-tty.select:select-filter sel))) (when (> (length f) 0)