Critical fixes: case→cond in %read-event, theme resolution, SGR mouse, scrollbox/text-input/textarea render stubs, test runner exit code, ASDF rename
CRITICAL: case b → cond in %read-event (input.lisp:280)
case with (and ...) predicate clauses treats keys as eql-compared
atoms — all range clauses were dead code. Every Ctrl+letter and
printable ASCII fell through to :unknown. text-input/textarea
widgets were non-functional with real terminal input. No test
coverage of %read-event masked this.
HIGH: Theme resolution wired (backend/modern.lisp, theme.lisp)
sgr-fg/sgr-bg now fall back to *theme-colors* hash for semantic
keywords (:accent, :text-muted, :background-element). *theme-colors*
exported from cl-tty.backend. load-preset populates it from preset
hex values. Previously all themed render output was invisible.
HIGH: SGR mouse parser wired (input.lisp:210-215)
parse-sgr-mouse was defined but never called. Now %read-escape-sequence
detects ESC[< prefix and routes to parse-sgr-mouse. Mouse drags,
releases, and scroll events now parse correctly.
MEDIUM: Rendering stubs replaced
- scrollbox: delegates to (render child backend) with position
offset via unwind-protect (was debug string 'child at ~D')
- text-input: draws value/placeholder at layout position
- textarea: draws visible lines at layout position
MEDIUM: hit-test uses component-layout-node (mouse.lisp:18-31)
Was checking nonexistent x/y/width/height slots. Now reads
layout-node-x/y/w/h via component-layout-node generic.
MEDIUM: test runner exit code (run-all-tests.lisp, cl-tty.asd)
run-all-tests.lisp exits 1 if any suite fails.
asdf:test-system exits 1 on failure.
Renamed :cl-tty-tests to :cl-tty/test (ASDF convention).
MEDIUM: draw-border respects x/y on simple-backend (simple.lisp:42-53)
Was writing to cursor position only. Now uses newlines+spaces
to reach specified coordinates (no escape sequences needed).
LOW: TabBar truncation off-by-one fixed (tabbar.lisp:47)
>= changed to > to avoid cutting tabs 2 chars early.
LOW: Scrollbar coordinates absolute (scrollbox.lisp:61-73)
Scrollbar drawn at viewport-relative (0,0). Now adds layout
node x/y offset for correct terminal positioning.
LOW: backend-write calls finish-output (modern.lisp:169)
LOW: load-preset no longer flips theme-mode (theme.lisp:43-45)
Mode toggle caused load-preset to load wrong variant on
second call.
All backported to org source files (org/text-input.org,
org/scrollbox-tabbar.org) so tangling produces matching .lisp.
392 tests pass, exit code 0.
This commit is contained in:
@@ -204,10 +204,14 @@
|
||||
(make-key-event :key :escape :raw (string #\Esc)))))
|
||||
;; CSI: ESC [ ...
|
||||
(#x5b
|
||||
(multiple-value-bind (params final-byte) (parse-csi-params)
|
||||
(multiple-value-bind (params final-byte raw) (parse-csi-params)
|
||||
(if (null final-byte)
|
||||
(make-key-event :key :escape :raw (string #\Esc))
|
||||
(if (and (char= (code-char final-byte) #\M)
|
||||
;; SGR mouse: ESC [ < ... m/M
|
||||
(if (and raw (plusp (length raw)) (char= (char raw 0) #\<))
|
||||
(or (parse-sgr-mouse raw)
|
||||
(make-key-event :key :unknown :raw raw))
|
||||
(if (and (char= (code-char final-byte) #\M)
|
||||
(>= (length params) 3))
|
||||
(let* ((p0 (first params)))
|
||||
(if (zerop (logand p0 #x40))
|
||||
@@ -252,7 +256,7 @@
|
||||
ctrl (logtest modifier 4)))
|
||||
(make-key-event :key (or key :unknown)
|
||||
:ctrl ctrl :alt alt :shift shift
|
||||
:raw (format nil "~C[~d~C" #\Esc param (code-char final-byte))))))))))
|
||||
:raw (format nil "~C[~d~C" #\Esc param (code-char final-byte)))))))))))
|
||||
;; ESC ESC
|
||||
(#x1b
|
||||
(make-key-event :key :escape :alt t :raw "\\e\\e"))
|
||||
@@ -273,24 +277,24 @@
|
||||
(let ((b (read-raw-byte :timeout timeout)))
|
||||
(unless b
|
||||
(return-from %read-event nil))
|
||||
(case b
|
||||
(#x1b
|
||||
(cond
|
||||
((= b #x1b)
|
||||
(%read-escape-sequence))
|
||||
(#x09
|
||||
((= b #x09)
|
||||
(make-key-event :key :tab :code #x09))
|
||||
(#x0a
|
||||
((= b #x0a)
|
||||
(make-key-event :key :enter :code #x0a))
|
||||
(#x0d
|
||||
((= b #x0d)
|
||||
(make-key-event :key :enter :code #x0d))
|
||||
((#x7f #x08)
|
||||
((or (= b #x7f) (= b #x08))
|
||||
(make-key-event :key :backspace :code b))
|
||||
((and (>= b #x01) (<= b #x1a))
|
||||
(let ((key (intern (string-upcase (string (code-char (+ b #x60)))) :keyword)))
|
||||
(make-key-event :key key :ctrl t :code b)))
|
||||
(#x1c (make-key-event :key :backslash :ctrl t :code b))
|
||||
(#x1d (make-key-event :key :rbracket :ctrl t :code b))
|
||||
(#x1e (make-key-event :key :caret :ctrl t :code b))
|
||||
(#x1f (make-key-event :key :underscore :ctrl t :code b))
|
||||
((= b #x1c) (make-key-event :key :backslash :ctrl t :code b))
|
||||
((= b #x1d) (make-key-event :key :rbracket :ctrl t :code b))
|
||||
((= b #x1e) (make-key-event :key :caret :ctrl t :code b))
|
||||
((= b #x1f) (make-key-event :key :underscore :ctrl t :code b))
|
||||
((and (>= b #x20) (<= b #x7e))
|
||||
(let ((ch (code-char b)))
|
||||
(make-key-event :key (intern (string (string-upcase ch)) :keyword)
|
||||
|
||||
Reference in New Issue
Block a user