我正在用普通的lisp写一个计时器,输出正在标准输出中显示。我正在尝试做的是更换输出而不打印换行并且没有并排打印,而是覆盖以前的输出,因此存在连续性错觉。
无论如何都可以在常见的lisp中执行此操作吗?
答案 0 :(得分:3)
好的,看完评论后,我明白了你的意图。从你原来的问题,我假设你想要替换/扩充其他一些代码的输出。但现在我明白了,你真正想要的是更新屏幕。仅使用基于流的IO无法做到这一点,您需要一些其他类型的IO库,如ncurses。
ncurses的Common Lisp绑定是系统cl-charms(在QuickLisp中可用)。没有特定于cl-charms的文档,但是在C中使用ncurses的文档几乎不会被应用。这是您正在描述的任务的简单实现,即。它会在屏幕的左上角显示(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")
。为了经常使用该库,您可能应该更改库源代码,并可能向开发人员建议修补程序。
从CLiki链接的cl-charms主页不可用,但http://gitorious.org/cl-charms的存储库是。
以下是我在示例中使用的ncurses / cl-charms函数的简短说明:
initscr
初始化ncurses。clear
清除屏幕。curs-set
设置游标可见性,0表示不可见。mvaddstr
将光标移动到坐标y,x并在那里写一个字符串,替换之前屏幕上的字符串。refresh
使屏幕上的更改实际可见。endwin
是你完成ncurses时要调用的清理函数。 <击>
如果我理解你正在尝试做什么,最好的方法似乎是创建一个新的输出流类(即fundamental-character-output-stream
的子类,假设你的实现支持Gray Streams)。您应该至少为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))
击> <击> 撞击>