mirror of
https://gitlab.com/eql/lqml.git
synced 2025-12-06 02:30:38 -08:00
53 lines
1.3 KiB
Common Lisp
53 lines
1.3 KiB
Common Lisp
;;; idea & most code from "ecl-readline.lisp"
|
|
|
|
(defpackage input-hook
|
|
(:use :cl)
|
|
(:export
|
|
#:add))
|
|
|
|
(provide :input-hook)
|
|
|
|
(in-package :input-hook)
|
|
|
|
(defvar *functions* nil)
|
|
|
|
(defun add (function)
|
|
(let ((stream (make-instance 'input-hook-stream)))
|
|
(push (cons stream function) *functions*)
|
|
stream))
|
|
|
|
(defclass input-hook-stream (gray:fundamental-character-input-stream)
|
|
((buffer :initform (make-string 0))
|
|
(index :initform 0)))
|
|
|
|
(defmethod gray:stream-read-char ((stream input-hook-stream))
|
|
(if (ensure-stream-data stream)
|
|
(with-slots (buffer index) stream
|
|
(let ((ch (char buffer index)))
|
|
(incf index)
|
|
ch))
|
|
:eof))
|
|
|
|
(defmethod gray:stream-unread-char ((stream input-hook-stream) character)
|
|
(with-slots (index) stream
|
|
(when (> index 0)
|
|
(decf index))))
|
|
|
|
(defmethod gray:stream-listen ((stream input-hook-stream))
|
|
nil)
|
|
|
|
(defmethod gray:stream-clear-input ((stream input-hook-stream))
|
|
nil)
|
|
|
|
(defmethod gray:stream-peek-char ((stream input-hook-stream))
|
|
(if (ensure-stream-data stream)
|
|
(with-slots (buffer index) stream
|
|
(char buffer index))
|
|
:eof))
|
|
|
|
(defun ensure-stream-data (stream)
|
|
(with-slots (buffer index) stream
|
|
(when (= index (length buffer))
|
|
(setf buffer (funcall (cdr (assoc stream *functions*)))
|
|
index 0))
|
|
buffer))
|