i’m writing a chronometer in common lisp, output is being displayed in standard-output. what i’m trying to do is replace the output without printing a newline and without printing side-by-side but by overwriting the previous output so there is an illusion of continuity.
is there anyway to do this in common lisp?
OK, after reading the comments, I understand your intentions much better. From you original question, I assumed you wanted to replace/augment the output of some other code. But now I understand, what you actually want is to update the screen. This cannot be done with stream-based IO alone, you need some other kind of IO library like ncurses.
A Common Lisp binding for ncurses is the system cl-charms (available in QuickLisp). There is no cl-charms specific documentation, but the documentation for using ncurses in C can be applied almost unchanged. Here is a simple implementation for the task you’re describing, ie. it displays (for 10 seconds) a clock in the left upper corner of the screen:
Two problems I’ve experienced with this:
This worked only in a terminal, not in the Emacs slime-repl buffer.
cl-charms couldn’t find my installation of the curses library by itself. It was looking for a library named “libcurses.so” or “libncurses.so”, but on my system, the library was only present with versioned names. So I had to use the
USE-VALUErestart during loading the library and provide the alternative value("libncurses.so.5")for the list of library names. For using the library often, you should probably want to change the library source code and maybe suggest a patch to the developers.The cl-charms homepage linked from CLiki is not available, but the repository at http://gitorious.org/cl-charms is.
Here’s a short explanation of the ncurses/cl-charms functions I used in the example:
initscrinitializes ncurses.clearclears the screen.curs-setsets cursor visibility, 0 means invisible.mvaddstrmoves the cursor to the coordinates y, x and writes a string there, replacing what was there on the screen previously.refreshmakes the changes to the screen actually visible.endwinis the clean-up function to call when you’re finished with ncurses.If I understand correctly what you’re trying to do, the best approach seems to be to create a new output stream class (i.e. a subclass of
fundamental-character-output-stream, assuming your implementation supports Gray Streams). You should probably provide methods specialised for your class at least forstream-write-charandstream-write-string.Then you could wrap code with a redefinition of
*standard-output*to an instance of your class, somewhat like this: