fix: parse-csi-sequence multi-value capture, read-raw-byte timeout, format args
- parse-csi-sequence: use multiple-value-bind to capture both params list and terminator byte (let* only takes primary value, discarding terminator, causing destructuring-bind to fail on empty list) - parse-csi-params: convert terminator byte to char via code-char for key table lookups and comparisons - read-raw-byte: check unix-simple-poll result before calling unix-read. When poll times out, returns nil immediately instead of blocking forever on unix-read
This commit is contained in:
@@ -43,10 +43,11 @@
|
|||||||
(#\Z . :back-tab)))
|
(#\Z . :back-tab)))
|
||||||
|
|
||||||
(defun parse-csi-params (params terminator extended)
|
(defun parse-csi-params (params terminator extended)
|
||||||
(let* ((key (if (find terminator '(#\~ #\u))
|
(let* ((term-char (code-char terminator))
|
||||||
|
(key (if (find term-char '(#\~ #\u))
|
||||||
(cdr (assoc (first params) *csi-tilde-table*))
|
(cdr (assoc (first params) *csi-tilde-table*))
|
||||||
(cdr (assoc terminator *csi-key-table*))))
|
(cdr (assoc term-char *csi-key-table*))))
|
||||||
(modifier (when (and (> (length params) 1) (not (find terminator '(#\~ #\u))))
|
(modifier (when (and (> (length params) 1) (not (find term-char '(#\~ #\u))))
|
||||||
(second params)))
|
(second params)))
|
||||||
(actual-modifier (when (> (length extended) 1) (second extended)))
|
(actual-modifier (when (> (length extended) 1) (second extended)))
|
||||||
(ctrl nil) (alt nil) (shift nil))
|
(ctrl nil) (alt nil) (shift nil))
|
||||||
@@ -58,14 +59,16 @@
|
|||||||
(setf shift (or shift (logtest actual-modifier 1))
|
(setf shift (or shift (logtest actual-modifier 1))
|
||||||
alt (or alt (logtest actual-modifier 2))
|
alt (or alt (logtest actual-modifier 2))
|
||||||
ctrl (or ctrl (logtest actual-modifier 4))))
|
ctrl (or ctrl (logtest actual-modifier 4))))
|
||||||
(if (eql terminator #\u)
|
(if (eql term-char #\u)
|
||||||
(let ((code (first params)))
|
(let ((code (first params)))
|
||||||
(make-key-event :key :codepoint :code code
|
(make-key-event :key :codepoint :code code
|
||||||
:ctrl ctrl :alt alt :shift shift
|
:ctrl ctrl :alt alt :shift shift
|
||||||
:raw (string (code-char code))))
|
:raw (string (code-char code))))
|
||||||
(make-key-event :key (or key :unknown)
|
(make-key-event :key (or key :unknown)
|
||||||
:ctrl ctrl :alt alt :shift shift
|
:ctrl ctrl :alt alt :shift shift
|
||||||
:raw (format nil "~C[~{~d~};~d~C" #\Esc params terminator)))))
|
:raw (if (consp params)
|
||||||
|
(format nil "~C[~{~d~};~d" #\Esc params terminator)
|
||||||
|
"")))))
|
||||||
|
|
||||||
(defun read-raw-byte (&key timeout)
|
(defun read-raw-byte (&key timeout)
|
||||||
(let* ((buf (make-array 1 :element-type '(unsigned-byte 8)))
|
(let* ((buf (make-array 1 :element-type '(unsigned-byte 8)))
|
||||||
@@ -74,9 +77,11 @@
|
|||||||
(sb-sys:with-pinned-objects (buf)
|
(sb-sys:with-pinned-objects (buf)
|
||||||
(let ((sap (sb-sys:vector-sap buf)))
|
(let ((sap (sb-sys:vector-sap buf)))
|
||||||
(if timeout-ms
|
(if timeout-ms
|
||||||
(progn (sb-unix:unix-simple-poll fd :input timeout-ms)
|
(let ((poll-result (sb-unix:unix-simple-poll fd :input timeout-ms)))
|
||||||
(let ((n (sb-unix:unix-read fd sap 1)))
|
(if (and poll-result (plusp poll-result))
|
||||||
(if (= n 1) (aref buf 0) (values nil :eof))))
|
(let ((n (sb-unix:unix-read fd sap 1)))
|
||||||
|
(if (= n 1) (aref buf 0) (values nil :eof)))
|
||||||
|
(values nil nil)))
|
||||||
(let ((n (sb-unix:unix-read fd sap 1)))
|
(let ((n (sb-unix:unix-read fd sap 1)))
|
||||||
(if (= n 1) (aref buf 0) (values nil :eof))))))))
|
(if (= n 1) (aref buf 0) (values nil :eof))))))))
|
||||||
|
|
||||||
@@ -160,14 +165,15 @@ Returns a mouse-event struct."
|
|||||||
(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))
|
(multiple-value-bind (params terminator)
|
||||||
(multiple-value-bind (p term) (read-param (lambda () (read-raw-byte)))
|
(if (and (>= b2 48) (<= b2 57))
|
||||||
(setf (fill-pointer extended) (length p))
|
(multiple-value-bind (p term) (read-param (lambda () (read-raw-byte)))
|
||||||
(replace extended p)
|
(setf (fill-pointer extended) (length p))
|
||||||
(values p term))
|
(replace extended p)
|
||||||
(progn (vector-push-extend b2 extended) (read-param (lambda () (read-raw-byte)))))))
|
(values p term))
|
||||||
(destructuring-bind (params terminator) params
|
(progn (vector-push-extend b2 extended)
|
||||||
|
(read-param (lambda () (read-raw-byte)))))
|
||||||
(parse-csi-params params terminator extended)))))))
|
(parse-csi-params params terminator extended)))))))
|
||||||
|
|
||||||
(defun utf8-decode (bytes)
|
(defun utf8-decode (bytes)
|
||||||
|
|||||||
Reference in New Issue
Block a user