From: ···············@gmail.com
Subject: dynamic binding of standard input?
Date: 
Message-ID: <1165108114.103923.296300@f1g2000cwa.googlegroups.com>
Hi,

I'm writing a newbie friendly IDE and have some basics up and running
but have hit my first problem: how to send user input back to Lisp. If
the user evaluates something like:

      (read-line)

I'd like to activate an 'edit control' to type input (I'm using LTk but
I don't think any of this is library specific).

My attempts so far have been rather naive:

1) bind *standard-input* directly to a text widget. This fails, I
believe, because I have no way of stopping to prompt the user for input
once the eval is reading the above code. So *standard-input* simply
hits eof before anyone has a chance to input anything.

2) bind *standard-input* to a stream returning function. I seem to run
into a typing error here. What I actually want to do is: every time
input is requested, _run_ my function (i.e. pop up a modal window
prompting the user for text, marshal this using
make-string-input-stream and return the stream with the text in it).
I'm not sure if this is possible (i.e. can I bind something that is
actually evaluated each time to *standard-input* or am I being
ridiculous?). I guess I was thinking of events / call-backs but as I
read this back, it does seem like nonsense...

Or is there an entirely different approach I could use?

As I mentioned in a previous thread, I'm not using Swank as I think it
will be too much for me to digest at this point in my Lisp learning but
if all of this is impossible then I guess I have no choice but to put
this project on hold for a while. This would be a shame though as I'm
already using the program to program with (for all but user input and
debugging anyway...).

Many thanks.

Phil

From: Bill Atkins
Subject: Re: dynamic binding of standard input?
Date: 
Message-ID: <m2wt59dbe8.fsf@bertrand.local>
···············@gmail.com writes:

> My attempts so far have been rather naive:
>
> 1) bind *standard-input* directly to a text widget. This fails, I
> believe, because I have no way of stopping to prompt the user for input
> once the eval is reading the above code. So *standard-input* simply
> hits eof before anyone has a chance to input anything.
>
> 2) bind *standard-input* to a stream returning function. I seem to run
> into a typing error here. What I actually want to do is: every time
> input is requested, _run_ my function (i.e. pop up a modal window
> prompting the user for text, marshal this using
> make-string-input-stream and return the stream with the text in it).
> I'm not sure if this is possible (i.e. can I bind something that is
> actually evaluated each time to *standard-input* or am I being
> ridiculous?). I guess I was thinking of events / call-backs but as I
> read this back, it does seem like nonsense...
>
> Or is there an entirely different approach I could use?

*STANDARD-INPUT* has to be bound to some kind of stream; the standard
functions won't know what to do if it's a function or an Ltk widget.  The
most straightforward way to achieve what you want is to use Gray
streams, if your implementation supports them.  Gray streams let you
define streams as CLOS classes.

You could perhaps define a class that inherits both from the Ltk text
widget class and also implements an input stream.  Then you *can* bind
*STANDARD-INPUT* directly to the text widget.
From: John Thingstad
Subject: Re: dynamic binding of standard input?
Date: 
Message-ID: <op.tjymyonkpqzri1@pandora.upc.no>
On Sun, 03 Dec 2006 02:08:34 +0100, <···············@gmail.com> wrote:

>
> 2) bind *standard-input* to a stream returning function. I seem to run
> into a typing error here. What I actually want to do is: every time
> input is requested, _run_ my function (i.e. pop up a modal window
> prompting the user for text, marshal this using
> make-string-input-stream and return the stream with the text in it).
> I'm not sure if this is possible (i.e. can I bind something that is
> actually evaluated each time to *standard-input* or am I being
> ridiculous?). I guess I was thinking of events / call-backs but as I
> read this back, it does seem like nonsense...
>

For this approach I suggest you look at the source code for Swank
the Lisp spesific part of SLIME that sets up the socket interface.
You could use a pipe also or even shared memory.
Some systems allow all three (MS SQL) though either one would do.
Event callback sounds like nonsense. Send a command and retrieve
the output in a shell. By the way are you aware that there is a
Lisp interface plugin for Eclipse?


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Pascal Bourguignon
Subject: Re: dynamic binding of standard input?
Date: 
Message-ID: <878xhp37gv.fsf@thalassa.informatimago.com>
···············@gmail.com writes:

> Hi,
>
> I'm writing a newbie friendly IDE and have some basics up and running
> but have hit my first problem: how to send user input back to Lisp. If
> the user evaluates something like:
>
>       (read-line)
>
> I'd like to activate an 'edit control' to type input (I'm using LTk but
> I don't think any of this is library specific).
>
> My attempts so far have been rather naive:
>
> 1) bind *standard-input* directly to a text widget. This fails, I
> believe, because I have no way of stopping to prompt the user for input
> once the eval is reading the above code. So *standard-input* simply
> hits eof before anyone has a chance to input anything.
>
> 2) bind *standard-input* to a stream returning function. I seem to run
> into a typing error here. What I actually want to do is: every time
> input is requested, _run_ my function (i.e. pop up a modal window
> prompting the user for text, marshal this using
> make-string-input-stream and return the stream with the text in it).
> I'm not sure if this is possible (i.e. can I bind something that is
> actually evaluated each time to *standard-input* or am I being
> ridiculous?). I guess I was thinking of events / call-backs but as I
> read this back, it does seem like nonsense...
>
> Or is there an entirely different approach I could use?
>
> As I mentioned in a previous thread, I'm not using Swank as I think it
> will be too much for me to digest at this point in my Lisp learning but
> if all of this is impossible then I guess I have no choice but to put
> this project on hold for a while. This would be a shame though as I'm
> already using the program to program with (for all but user input and
> debugging anyway...).

Note that there are several stream variables:

    *standard-input*
    *standard-output*
    *trace-output*
    *error-output*
    *query-io*
    *terminal-io*
    *debug-io*

All of them should be bound to some stream.  But you can use
SYNONYM-STREAM to redirect one to another.


What you could in your IDE, is to provide some "terminal emulation"
windows, hooked to these various stream.  You could have only one, and
use SYNONYM-STREAM to hook the threads to it.  To implement the stream
going between CL and this IDE window, you'd have to write a subclass
of GRAY-STREAM (this is not in the CL standard, but a de-facto
standard extension).

These windows could be hidden, until the user writes to or reads from
the associated stream.


In some environment, even if the main user interface is on a GUI, the
program can still use the terminal and the console for some of its
stream I/O.  (eg. on MacOSX you could use NSLog for the *trace-output*
(at least in production code)).  

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

IMPORTANT NOTICE TO PURCHASERS: The entire physical universe,
including this product, may one day collapse back into an
infinitesimally small space. Should another universe subsequently
re-emerge, the existence of this product in that universe cannot be
guaranteed.
From: ···············@gmail.com
Subject: Re: dynamic binding of standard input?
Date: 
Message-ID: <1165166365.887850.251210@l12g2000cwl.googlegroups.com>
On Dec 3, 1:08 am, ···············@gmail.com wrote:

> but have hit my first problem: how to send user input back to Lisp. If

Many thanks to everyone that replied. I tried a few of these ideas but
I think I need to read up more about streams in Common Lisp.

Thanks,
Phil
From: Timofei Shatrov
Subject: Re: dynamic binding of standard input?
Date: 
Message-ID: <45729815.3258064@news.readfreenews.net>
On 2 Dec 2006 17:08:34 -0800, ···············@gmail.com tried to confuse
everyone with this message:

>Hi,
>
>I'm writing a newbie friendly IDE and have some basics up and running
>but have hit my first problem: how to send user input back to Lisp. If
>the user evaluates something like:
>
>      (read-line)
>
>I'd like to activate an 'edit control' to type input (I'm using LTk but
>I don't think any of this is library specific).

You need to bind *standard-input* to a Gray stream which does what you want.

The following example is in CLISP:

(Warning: some parentheses may be unmatched)

(defclass msgbox-in (gray:fundamental-character-input-stream)
  ((buffer :initform nil :accessor buffer)))

(defmethod gray:stream-read-char :before ((s msgbox-in))
  (unless (buffer s) (read-from-msgbox s)))

;;;read-from-msgbox shows input box and when the user enters something  
;;;it fills (buffer s) with the contents of the text box. 

(defmethod gray:stream-read-char ((s msgbox-in))
  (let* ((l (length (buffer s)))
         (c (when (> l 0) (elt (buffer s) 0)))
         (rest (when (> l 0) (subseq (buffer s) 1))))
    (if c (progn (setf (buffer s) rest) c) 
          (progn (setf (buffer s) nil) :eof))))

;;This probably shouldn't be called when the buffer is empty
;;I don't even know when it is called at all
(defmethod gray:stream-unread-char ((s msgbox-in) c)
  (let ((new (make-string (1+ (length (buffer s))))))
    (setf (elt new 0) c)
    (setf (subseq new 1) (buffer s))
    (setf (buffer s) new)))

(defmethod gray:stream-read-line :before ((s msgbox-in))
  (unless (buffer s) (read-from-msgbox s)))

(defmethod gray:stream-read-line ((s msgbox-in))
   (let ((what (buffer s)))
        (setf (buffer s) nil)
        what))

-- 
|Don't believe this - you're not worthless              ,gr---------.ru
|It's us against millions and we can't take them all... |  ue     il   |
|But we can take them on!                               |     @ma      |
|                       (A Wilhelm Scream - The Rip)    |______________|