在lisp中替换/覆盖标准输出

时间:2011-12-25 22:01:39

标签: lisp overwrite

我正在用普通的lisp写一个计时器,输出正在标准输出中显示。我正在尝试做的是更换输出而不打印换行并且没有并排打印,而是覆盖以前的输出,因此存在连续性错觉。

无论如何都可以在常见的lisp中执行此操作吗?

1 个答案:

答案 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-charstream-write-string提供专门针对您的课程的方法。

然后你可以将重新定义*standard-output*的代码包装到你的类的实例中,有点像这样:

(let ((*standard-output* (make-instance 'your-stream-class
                                        :target *standard-output*)))
  (function-to-be-called-with-wrapped-standard-output))

<击>