[plt-dev] Terminal control

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Tue Mar 10 18:44:29 EDT 2009

Cool. I'll try these out!

Jay

On Tue, Mar 10, 2009 at 4:42 PM, Eli Barzilay <eli at barzilay.org> wrote:
> On Mar 10, Matthew Flatt wrote:
>> At Tue, 10 Mar 2009 16:06:26 -0600, Jay McCarthy wrote:
>> > Don't ask why, but I'd like to do a terminal app with PLT.
>> >
>> > But I can figure out how to capture key presses as they are
>> > done. I can type something in and press enter, but I can't capture
>> > the key right when it is pressed, do something, and NOT print it
>> > out.
>> >
>> > I assumed that read-byte would do it, but apparently not.
>> >
>> > Any suggestions?
>>
>> You probably want to use the C library's "termios" functions to
>> control the terminal associated with stdin. Try `man cfmakeraw' for
>> more information.
>>
>> You'll also need scheme_get_port_fd() to go from a Scheme port to a
>> file descriptor. (Yep, I see the typo in the docs for that
>> one... fixed in SVN.)
>
> It might be easier to just use stty, which can get you that kind of
> control.  Here's some code that demonstrates how to get single
> characters as they come, without echoing them back.  (I've been using
> variations of this for a long time for all kinds of convenient
> scripts.)
>
>
> #!/bin/env mzscheme
>
> #lang scheme/base
>
> (require scheme/system)
>
> (define (call-with-stty thunk)
>  (define stty-exe
>    (or (find-executable-path "stty")
>        (error 'stty "could not find executable")))
>  (define (stty . args)
>    (or (apply system* stty-exe args)
>        (error 'stty "couldn't run with ~e" args)))
>  (define (get)
>    (let ([o (open-output-string)])
>      (parameterize ([current-output-port o])
>        (stty "-g")
>        (regexp-replace #rx"\r?\n$" (get-output-string o) ""))))
>  (let ([settings (get)])
>    (dynamic-wind (lambda () (stty "raw" "-echo" "opost"))
>                  thunk
>                  (lambda () (stty settings)))))
>
> (call-with-stty
>  (lambda ()
>    (let loop ()
>      (printf "Hit any key, q to exit: ")
>      (flush-output)
>      (let ([ch (read-char)])
>        (printf "~s\n" ch)
>        (unless (eq? ch #\q) (loop))))))
>
>
>
> --
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                  http://www.barzilay.org/                 Maze is Life!
>



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://teammccarthy.org/jay

"The glory of God is Intelligence" - D&C 93


Posted on the dev mailing list.