Reputation: 978
I'm trying to convince SBCL that the charpos of a terminal is back to 0 after read-line
.
For instance, the following piece of code
(progn
(format *query-io* "input: ")
(force-output *query-io*)
(prog1
(read-line *query-io*)
(write (sb-impl::charpos *query-io*))))
would print 7 (or 14, 21, ... depending on how many times you run it) despite the fact that after read-line
charpos
should be back to 0.
Thanks
Upvotes: 1
Views: 149
Reputation: 13914
So, here's the thing …
The easy way:
If you really want to ensure that you reach the left margin, you can always use fresh-line
to do so.
SB-IMPL::CHARPOS
is the position in characters from the left margin of one output stream. It's not documented or exported, but the comment on ANSI streams points out:
:charpos - Return current output position on the line.
It is not the cursor position on the screen when you mix together streams, and (as you've discovered), it does not track input sides of bidirectional streams.
Its Gray Streams accessor is stream-line-column
Return the column number where the next character will be written, or NIL if that is not meaningful for this stream. The first column on a line is numbered 0. This function is used in the implementation of PPRINT and the FORMAT ~T directive. For every character output stream class that is defined, a method must be defined for this function, although it is permissible for it to always return NIL.
If you want to wrap *query-io*
in such a way that you can specify the apparent output-column to the system — eg, because you expect that another stream (the input side's echo) has sent a new line — you could wrap it in a Gray stream class of your own, and do your own internal reckoning of what that method “should” return. (Basically just a defclass
, and implementations of make-instance :after
and stream-line-column
)
But, I don't think that's a good idea in general …
Keep in mind that it's possible for *query-io*
to draw its input from a separate window/widget than where its output appears — eg, I've seen examples where a bidirectional stream in CLIM printed output into an upper pane and collected input from a minibuffer below (like many Internet Relay Chat programs), so if you're aiming for any degree of portability, it's not safe to assume that your output to that stream, and the user's input, will appear comingled on the screen.
It's also not entirely safe to assume that the user has to enter a newline to finish their input — it's allowable that the Return that the user pressed might not print a newline; eg, it might clear their input box. They might also have finished input by clicking an “OK” button, for example.
If you're certain that *query-io*
is connected to a terminal that has a screen editor — ie, a terminal like Gnome Terminal and not, say, a Slime session — you can use (as @coredump suggested) CL-Charms https://github.com/HiTECNOLOGYs/cl-charms or something similar to position the cursor accurately within the window.
Upvotes: 1