[plt-dev] Terminal control

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Mar 10 18:42:56 EDT 2009

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!


Posted on the dev mailing list.