[plt-scheme] Custom READ?

From: Katsmall the Wise (kela_bit at netvision.net.il)
Date: Mon Mar 3 16:32:45 EST 2003

What I would do, Billy, is make a pipe, with every keyboard click 
written to the port in another thread, like this:
; this has not been tested for errors, by the way.
(define (add-write-event-to-keymap event keymap output)
  ; A little hard to explain, so here's an example:
  ; (add-write-event-to-keymap "c:a" keymap output-port) adds the event
  ; c:a (ctrl+a) to the keymap, which when called writes "c:a" to the
  ; output-port, followed by a newline.
  (define function-name (string-append event "-handler"))
  (send keymap add-function function-name
        (lambda args
          (display event output)
          (newline)))
  (send keymap map-function event function-name))

(define no-modifier-events (list "a" "b" "c" ... "z" ; letters
                                 "0" "1" "2" ... "9" ; digits
                                 "leftbutton" "rightbutton" 
"centerbutton" "leftbuttonup" ... "f24"))

(define (add-write-event-for-each-modifier-option-to-keymap event keymap 
output-port)
  (define (add-1 s c a m d)
    (add-write-event-to-keymap (string-append (if s "~s:" "s:")
                                              (if c "~c:" "c:")
                                              (if c "~a:" "a:")
                                              (if c "~m:" "m:")
                                              (if c "~d:" "d:")
                                              event)
                               keymap
                               output-port))
  (for-each (lambda (s)
              (for-each (lambda (c)
                          (for-each (lambda (a)
                                      (for-each (lambda (m)
                                                  (for-each (lambda (d)
                                                              (add-1 s c 
a m d)))
                                                  `(#t #f)))
                                      `(#t #f)))
                          `(#t #f)))
              `(#t #f)))
  `(#t #f))

(define (make-into-input-port obj)
  ; this procedure takes an object (one that has a keymap, not sure which
  ; ones have it), and makes it into an input port.
  (define-values (i o)
    (make-pipe))
  (define keymap (make-keymap))
  (for-each add-write-event-for-each-modifier-option-to-keymap 
no-modifier-events keymap o)
  i)

I know, it's a little (or a lot) inefficient - but it works. I think. 
Well you can try at least, and Robby'll probably think of a better way 
to do it for you...
Billy wrote:

>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
>I am experimenting with writing a Scheme-based command shell for Windows and have the
>following problem.
>
>Rather than using the standard READ-LINE, READ-CHAR, etc routines which hang until end
>of line or eof I'd like to intercept key presses as they occur.  This would allow me to
>do things like command line completion on [TAB] (like bash), [CTRL+R] to search command
>history, etc.  I "think" I need to use MAKE-CUSTOM-INPUT-PORT for this.
>
>1) Is this correct?  What are my other alternatives (e.g., would setting
>PORT-READ-HANDLER be more appropriate)?
>
>2) If I do use MAKE-CUSTOM-INPUT-PORT, do I need to write a C module (linked into a DLL)
>to handle all the keyboard events or can it all be done within Scheme?
>
>
>Also, it might be useful to know that the application is text mode (no GUI) and once I
>get it debugged I will compile it to a stand-alone application.
>
>Thanks in advance,
>-billy
>
>  
>



Posted on the users mailing list.