ОК, после прочтения комментариев, я гораздо лучше понимаю ваши намерения.Исходя из исходного вопроса, я предположил, что вы хотите заменить / дополнить вывод какого-либо другого кода.Но теперь я понимаю, что вы на самом деле хотите обновить экран .Это невозможно сделать с помощью потокового ввода-вывода в одиночку, вам нужен какой-то другой вид библиотеки ввода-вывода, такой как ncurses.
Связывание Common Lisp для ncurses - это системные cl-charms (доступно в QuickLisp).Специальной документации по cl-charms не существует, но документация по использованию ncurses в C может применяться практически без изменений.Вот простая реализация задачи, которую вы описываете, т.е.в левом верхнем углу экрана (на 10 секунд) отображаются часы:
(defun clock ()
(charms:initscr)
(charms:clear)
(charms:curs-set 0)
(loop with start = (get-universal-time)
do (multiple-value-bind (s m h) (get-decoded-time)
(charms:mvaddstr 0 0 (format nil "~2,'0d:~2,'0d:~2,'0d" h m s)))
(charms:refresh)
until (>= (- (get-universal-time) start) 10))
(charms:endwin))
Две проблемы, с которыми я столкнулся при этом:
Это сработалотолько в терминале, а не в буфере Emacs slime-repl.
cl-charms не смог найти мою установку библиотеки curses самостоятельно.Она искала библиотеку с именем "libcurses.so" или "libncurses.so", но в моей системе библиотека присутствовала только с версионными именами.Поэтому мне пришлось использовать перезапуск USE-VALUE
во время загрузки библиотеки и указать альтернативное значение ("libncurses.so.5")
для списка имен библиотек.Для частого использования библиотеки вам, вероятно, следует изменить исходный код библиотеки и, возможно, предложить разработчикам патч.
Домашняя страница cl-charms, связанная с CLiki, недоступна, нохранилище в http://gitorious.org/cl-charms равно.
Вот краткое объяснение функций ncurses / cl-charms, которые я использовал в примере:
initscr
инициализирует ncurses. clear
очищает экран. curs-set
устанавливает видимость курсора, 0 означает невидимый. mvaddstr
перемещает курсор к координатам y, x и записываеттам есть строка, заменяющая то, что было на экране ранее. refresh
делает изменения на экране действительно видимыми. endwin
- это функция очистки, которая вызывается, когда вызакончили работу с ncurses.
Если я правильно понимаю, что вы пытаетесь сделать, лучшим подходом, похоже, будет создание нового класса выходного потока (то есть подкласса).fundamental-character-output-stream
при условии вашей реализацииподдерживает серые потоки).Вы, вероятно, должны предоставить методы, специализированные для вашего класса, по крайней мере для stream-write-char
и stream-write-string
.
Тогда вы можете обернуть код с переопределением *standard-output*
в экземпляр вашего класса, примерно так:
(let ((*standard-output* (make-instance 'your-stream-class
:target *standard-output*)))
(function-to-be-called-with-wrapped-standard-output))