54 lines
1.3 KiB
Racket
54 lines
1.3 KiB
Racket
#lang racket/base
|
|
(require racket/match
|
|
racket/list
|
|
racket/system
|
|
ansi)
|
|
|
|
(define stty-minus-f-arg-string
|
|
(case (system-type 'os)
|
|
((macosx) "-f")
|
|
(else "-F")))
|
|
|
|
(define (read-until ip char)
|
|
(define byte (char->integer char))
|
|
(apply bytes
|
|
(let loop ()
|
|
(match (read-byte ip)
|
|
[(== byte) empty]
|
|
[next (cons next (loop))]))))
|
|
|
|
(define (screen-size)
|
|
(define tty-str "/dev/tty")
|
|
(system* "/bin/stty"
|
|
stty-minus-f-arg-string
|
|
tty-str
|
|
"raw"
|
|
"-echo")
|
|
(define-values (in out)
|
|
(open-input-output-file tty-str #:exists 'update))
|
|
(write-bytes #"\e[18t" out) (flush-output out)
|
|
(dynamic-wind
|
|
void
|
|
(λ ()
|
|
(match (read-until in #\;)
|
|
[#"\e[8"
|
|
(define row-s (read-until in #\;))
|
|
(define col-s (read-until in #\t))
|
|
(values (bytes->number row-s)
|
|
(bytes->number col-s))]
|
|
[_ (values #f #f)]))
|
|
(λ ()
|
|
(close-input-port in)
|
|
(close-output-port out)
|
|
(system* "/bin/stty"
|
|
stty-minus-f-arg-string
|
|
tty-str
|
|
"cooked"
|
|
"echo"))))
|
|
|
|
(define (bytes->number bs)
|
|
(string->number (bytes->string/utf-8 bs)))
|
|
|
|
(module+ main
|
|
(screen-size))
|