diff --git a/org/channel-tui-main.org b/org/channel-tui-main.org index 0213f9e..9561234 100644 --- a/org/channel-tui-main.org +++ b/org/channel-tui-main.org @@ -955,51 +955,51 @@ supplied (e.g. \"/\"), pre-fill the select filter with it." (when (> (length f) 0) (setf (cl-tty.select:select-filter sel) (subseq f 0 (1- f)))))))) - (on-key ch)))))))) - ;; Keyboard reader with CSI escape detection - (handler-case - (sb-ext:with-timeout 0.1 - (let* ((raw-ch (read-char-no-hang *standard-input* nil nil))) - (when raw-ch - (let* ((code (char-code raw-ch)) - (esc-seq (and (= code 27) - ;; Poll for up to 20ms to collect CSI bytes - (let ((b nil) (t2 nil)) - (dotimes (_ 20) - (when (listen *standard-input*) - (setq b (read-char *standard-input* nil nil)) - (return)) - (sleep 0.001)) - (and b (char= b #\[) - (dotimes (_ 10) - (when (listen *standard-input*) - (setq t2 (read-char *standard-input* nil nil)) - (return)) - (sleep 0.001)) - (case (and t2 (char-code t2)) - (65 :up) (66 :down) - (67 :right) (68 :left) - (72 :home) (70 :end) - (otherwise :escape)))))) - (queue-event - (list :type :key - :payload (list :code code - :ch (or esc-seq - (cond - ((= code 13) :enter) - ((= code 10) :enter) - ((= code 27) :escape) - ((= code 9) :tab) - ((or (= code 127) (= code 8)) :backspace) - ((and (>= code 1) (<= code 26)) - (intern - (string-upcase - (format nil "CTRL-~a" - (code-char (+ #x60 code)))) - :keyword)) - (t code)))))))))))) - (sb-ext:timeout ()) - ;; Check for terminal resize (SIGWINCH sets this flag) + (on-key ch)))))))) + ;; Keyboard reader: poll with 0.1s timeout via listen (no sb-ext:timeout) + (dotimes (_ 10) + (when (listen *standard-input*) + (let* ((raw-ch (read-char-no-hang *standard-input* nil nil)) + (code (and raw-ch (char-code raw-ch))) + (esc-seq (and (= code 27) + (let ((b nil) (t2 nil)) + (dotimes (_ 20) + (when (listen *standard-input*) + (setq b (read-char *standard-input* nil nil)) + (return)) + (sleep 0.001)) + (and b (char= b #\[) + (dotimes (_ 10) + (when (listen *standard-input*) + (setq t2 (read-char *standard-input* nil nil)) + (return)) + (sleep 0.001)) + (case (and t2 (char-code t2)) + (65 :up) (66 :down) + (67 :right) (68 :left) + (72 :home) (70 :end) + (otherwise :escape))))))) + (when raw-ch + (queue-event + (list :type :key + :payload (list :code code + :ch (or esc-seq + (cond + ((= code 13) :enter) + ((= code 10) :enter) + ((= code 27) :escape) + ((= code 9) :tab) + ((or (= code 127) (= code 8)) :backspace) + ((and (>= code 1) (<= code 26)) + (intern + (string-upcase + (format nil "CTRL-~a" + (code-char (+ #x60 code)))) + :keyword)) + (t code))))))) + (return))) + (sleep 0.01)) + ;; Check for terminal resize (SIGWINCH sets this flag) (when (boundp 'cl-tty.input::*terminal-resized-p*) (when cl-tty.input::*terminal-resized-p* (setf cl-tty.input::*terminal-resized-p* nil) diff --git a/passepartout b/passepartout index 8eebba4..17b02ba 100755 --- a/passepartout +++ b/passepartout @@ -397,14 +397,16 @@ case "$COMMAND" in (compile-file src :output-file fasl :verbose nil :print nil)) (load fasl :verbose nil :print nil)))) (in-package :passepartout) -(handler-bind ((error (lambda (c) (ignore-errors - (with-open-file (f (merge-pathnames ".cache/passepartout/tui-crash.log" (user-homedir-pathname)) - :direction :output :if-exists :supersede :if-does-not-exist :create) - (format f "CRASH: ~a~%~%" c) (sb-debug:print-backtrace :count 50 :stream f) (finish-output f))) - (format t "~%=== TUI CRASH ===~%CRASH: ~a~%" c) - (format t "Full backtrace saved to ~~/.cache/passepartout/tui-crash.log~%") - (sleep 3) (finish-output) (uiop:quit 1)))) - (passepartout.channel-tui:tui-main)) +(handler-case + (passepartout.channel-tui:tui-main) + (error (c) + (ignore-errors + (with-open-file (f (merge-pathnames ".cache/passepartout/tui-crash.log" (user-homedir-pathname)) + :direction :output :if-exists :supersede :if-does-not-exist :create) + (format f "CRASH: ~a~%~%" c) (sb-debug:print-backtrace :count 50 :stream f) (finish-output f))) + (format t "~%=== TUI CRASH ===~%CRASH: ~a~%" c) + (format t "Full backtrace saved to ~~/.cache/passepartout/tui-crash.log~%") + (sleep 3) (finish-output))) (uiop:quit 0) LISPEOF # Capture terminal dimensions in non-standard env vars