v1.1.0: fix CSI parser destructuring-bind crash on nil params
parse-csi-sequence used destructuring-bind on a single return value, failing when the CSI sequence had no parameters (e.g. plain arrow keys ESC[A). Capture multiple return values via multiple-value-list instead of relying on let* which only captures the primary value.
This commit is contained in:
@@ -627,22 +627,27 @@ to ~parse-csi-params~ for modifier extraction.
|
|||||||
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/input.lisp
|
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/input.lisp
|
||||||
(defun parse-csi-sequence ()
|
(defun parse-csi-sequence ()
|
||||||
(flet ((read-param (next-fn) (let ((acc nil))
|
(flet ((read-param (next-fn) (let ((acc nil))
|
||||||
(loop for b = (funcall next-fn)
|
(loop for b = (funcall next-fn)
|
||||||
do (if (and (>= b 48) (<= b 57))
|
do (if (and (>= b 48) (<= b 57))
|
||||||
(push (- b 48) acc)
|
(push (- b 48) acc)
|
||||||
(return (values (reverse acc) b)))))))
|
(return (values (reverse acc) b)))))))
|
||||||
(let* ((b2 (read-raw-byte)))
|
(let* ((b2 (read-raw-byte)))
|
||||||
(if (= b2 60) ;; < — SGR mouse marker
|
(if (= b2 60) ;; < — SGR mouse marker
|
||||||
(%parse-sgr-mouse)
|
(%parse-sgr-mouse)
|
||||||
(let* ((extended (make-array 8 :element-type 'fixnum :fill-pointer 0))
|
(let* ((extended (make-array 8 :element-type 'fixnum :fill-pointer 0))
|
||||||
(params (if (and (>= b2 48) (<= b2 57))
|
(parsed (if (and (>= b2 48) (<= b2 57))
|
||||||
(multiple-value-bind (p term) (read-param (lambda () (read-raw-byte)))
|
;; Digit branch: read params with their digits
|
||||||
(setf (fill-pointer extended) (length p))
|
(let ((r (multiple-value-list (read-param (lambda () (read-raw-byte))))))
|
||||||
(replace extended p)
|
(let ((p (first r)))
|
||||||
(values p term))
|
(setf (fill-pointer extended) (length p))
|
||||||
(progn (vector-push-extend b2 extended) (read-param (lambda () (read-raw-byte)))))))
|
(replace extended p))
|
||||||
(destructuring-bind (params terminator) params
|
r)
|
||||||
(parse-csi-params params terminator extended)))))))
|
;; Non-digit branch: b2 is a direct CSI terminator
|
||||||
|
(progn (vector-push-extend b2 extended)
|
||||||
|
(multiple-value-list (read-param (lambda () (read-raw-byte))))))))
|
||||||
|
(let ((params (first parsed))
|
||||||
|
(terminator (or (second parsed) 0)))
|
||||||
|
(parse-csi-params (or params '()) terminator extended)))))))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** UTF-8 decoder
|
** UTF-8 decoder
|
||||||
@@ -1700,7 +1705,7 @@ for users writing ~:ctrl+p~ in their keymaps.
|
|||||||
(let ((mod-str (subseq name 0 plus))
|
(let ((mod-str (subseq name 0 plus))
|
||||||
(key-str (subseq name (1+ plus))))
|
(key-str (subseq name (1+ plus))))
|
||||||
(and (eql (intern key-str :keyword)
|
(and (eql (intern key-str :keyword)
|
||||||
(key-event-key event))
|
(intern (string-upcase (symbol-name (key-event-key event))) :keyword))
|
||||||
(cond
|
(cond
|
||||||
((string= mod-str "CTRL") (key-event-ctrl event))
|
((string= mod-str "CTRL") (key-event-ctrl event))
|
||||||
((string= mod-str "ALT") (key-event-alt event))
|
((string= mod-str "ALT") (key-event-alt event))
|
||||||
|
|||||||
Reference in New Issue
Block a user