Add lux support
This commit is contained in:
parent
8676b3736b
commit
8d66b2c284
68
draw.rkt
68
draw.rkt
|
@ -16,7 +16,8 @@
|
||||||
[underline . ,A:style-underline]))
|
[underline . ,A:style-underline]))
|
||||||
(define current-fg (make-parameter 'default))
|
(define current-fg (make-parameter 'default))
|
||||||
(define current-bg (make-parameter 'default))
|
(define current-bg (make-parameter 'default))
|
||||||
(define current-display-drawing-parameters? (make-parameter #t))
|
(define current-display-drawing-parameters?
|
||||||
|
(make-parameter (current-output-port)))
|
||||||
(define symbol->color
|
(define symbol->color
|
||||||
`#hasheq(
|
`#hasheq(
|
||||||
[black . 0] [red . 1] [green . 2] [yellow . 3]
|
[black . 0] [red . 1] [green . 2] [yellow . 3]
|
||||||
|
@ -32,8 +33,9 @@
|
||||||
(A:select-graphic-rendition A:style-default-background-color)
|
(A:select-graphic-rendition A:style-default-background-color)
|
||||||
(A:select-xterm-256-background-color (hash-ref symbol->color c))))
|
(A:select-xterm-256-background-color (hash-ref symbol->color c))))
|
||||||
(define (set-drawing-parameters!)
|
(define (set-drawing-parameters!)
|
||||||
(when (current-display-drawing-parameters?)
|
(cond
|
||||||
(display (get-drawing-parameters))))
|
[(current-display-drawing-parameters?)
|
||||||
|
=> (λ (op) (display (get-drawing-parameters) op))]))
|
||||||
(define (get-drawing-parameters)
|
(define (get-drawing-parameters)
|
||||||
(string-append
|
(string-append
|
||||||
(A:select-graphic-rendition (hash-ref symbol->style (current-style)))
|
(A:select-graphic-rendition (hash-ref symbol->style (current-style)))
|
||||||
|
@ -45,39 +47,43 @@
|
||||||
;; ! : (row col char -> void) row col -> bool
|
;; ! : (row col char -> void) row col -> bool
|
||||||
(struct raart (w h !))
|
(struct raart (w h !))
|
||||||
|
|
||||||
(define (draw x [row 1] [col 1]
|
(define (draw x
|
||||||
|
#:output [op (current-output-port)]
|
||||||
#:clear? [clear? #t])
|
#:clear? [clear? #t])
|
||||||
(match-define (raart w h !) x)
|
(match-define (raart w h !) x)
|
||||||
(display (A:dec-soft-terminal-reset))
|
(display (A:dec-soft-terminal-reset) op)
|
||||||
(when clear?
|
(when clear?
|
||||||
(display (A:clear-screen/home)))
|
(display (A:clear-screen/home) op))
|
||||||
(set-drawing-parameters!)
|
(parameterize ([current-display-drawing-parameters? op])
|
||||||
(! (λ (r c ch)
|
(set-drawing-parameters!)
|
||||||
(display (A:goto r c))
|
(! (λ (r c ch)
|
||||||
(display ch)
|
(display (A:goto r c) op)
|
||||||
#t)
|
(when ch (display ch op))
|
||||||
row col)
|
#t)
|
||||||
(display (A:goto (+ row h) (+ col w))))
|
1 1))
|
||||||
|
(flush-output op))
|
||||||
|
|
||||||
(define (draw-here x)
|
(define (draw-here x #:output [op (current-output-port)])
|
||||||
(match-define (raart w h !) x)
|
(match-define (raart w h !) x)
|
||||||
(define init-dp (get-drawing-parameters))
|
(define init-dp (get-drawing-parameters))
|
||||||
(define def (cons init-dp #\space))
|
(define def (cons init-dp #\space))
|
||||||
(define rows (build-vector h (λ (i) (make-vector w def))))
|
(define rows (build-vector h (λ (i) (make-vector w def))))
|
||||||
(! (λ (r c ch)
|
(parameterize ([current-display-drawing-parameters? #f])
|
||||||
(vector-set! (vector-ref rows r) c
|
(! (λ (r c ch)
|
||||||
(cons (get-drawing-parameters) ch))
|
(vector-set! (vector-ref rows r) c
|
||||||
#t)
|
(cons (get-drawing-parameters) ch))
|
||||||
0 0)
|
#t)
|
||||||
|
0 0))
|
||||||
(for/fold ([last-dp init-dp]) ([r (in-vector rows)])
|
(for/fold ([last-dp init-dp]) ([r (in-vector rows)])
|
||||||
(begin0
|
(begin0
|
||||||
(for/fold ([last-dp last-dp]) ([dp*ch (in-vector r)])
|
(for/fold ([last-dp last-dp]) ([dp*ch (in-vector r)])
|
||||||
(match-define (cons this-dp ch) dp*ch)
|
(match-define (cons this-dp ch) dp*ch)
|
||||||
(unless (string=? this-dp last-dp)
|
(unless (string=? this-dp last-dp)
|
||||||
(display this-dp))
|
(display this-dp op))
|
||||||
(display ch)
|
(display ch op)
|
||||||
this-dp)
|
this-dp)
|
||||||
(newline)))
|
(newline op)))
|
||||||
|
(flush-output op)
|
||||||
(void))
|
(void))
|
||||||
|
|
||||||
(define-syntax (with-maybe-parameterize stx)
|
(define-syntax (with-maybe-parameterize stx)
|
||||||
|
@ -334,6 +340,12 @@
|
||||||
(when ? (f))
|
(when ? (f))
|
||||||
?)))
|
?)))
|
||||||
|
|
||||||
|
(define (place-cursor-after x cr cc)
|
||||||
|
(match-define (raart w h !) x)
|
||||||
|
(raart w h (λ (d r c)
|
||||||
|
(strict-or (! d r c)
|
||||||
|
(d cr cc #f)))))
|
||||||
|
|
||||||
(define style/c (apply or/c (hash-keys symbol->style)))
|
(define style/c (apply or/c (hash-keys symbol->style)))
|
||||||
(define color/c (apply or/c (hash-keys symbol->color)))
|
(define color/c (apply or/c (hash-keys symbol->color)))
|
||||||
(define valign/c (or/c 'top 'center 'bottom))
|
(define valign/c (or/c 'top 'center 'bottom))
|
||||||
|
@ -341,13 +353,14 @@
|
||||||
(provide
|
(provide
|
||||||
(contract-out
|
(contract-out
|
||||||
[raart? (-> any/c boolean?)]
|
[raart? (-> any/c boolean?)]
|
||||||
[draw-here (-> raart? void?)]
|
|
||||||
[draw
|
[draw
|
||||||
(->* (raart?)
|
(->* (raart?)
|
||||||
(exact-positive-integer?
|
(#:output output-port?
|
||||||
exact-positive-integer?
|
|
||||||
#:clear? boolean?)
|
#:clear? boolean?)
|
||||||
void?)]
|
void?)]
|
||||||
|
[draw-here
|
||||||
|
(->* (raart?) (#:output output-port?)
|
||||||
|
void?)]
|
||||||
[style/c contract?]
|
[style/c contract?]
|
||||||
[style (-> style/c raart? raart?)]
|
[style (-> style/c raart? raart?)]
|
||||||
[color/c contract?]
|
[color/c contract?]
|
||||||
|
@ -404,5 +417,8 @@
|
||||||
raart?)]
|
raart?)]
|
||||||
[text-rows (-> (listof (listof any/c))
|
[text-rows (-> (listof (listof any/c))
|
||||||
(listof (listof raart?)))]
|
(listof (listof raart?)))]
|
||||||
[if-drawn (-> (-> any) raart? raart?)])
|
[if-drawn (-> (-> any) raart? raart?)]
|
||||||
|
[place-cursor-after
|
||||||
|
(-> raart? exact-positive-integer? exact-positive-integer?
|
||||||
|
raart?)])
|
||||||
place-at*)
|
place-at*)
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
#lang racket/base
|
||||||
|
(require racket/match
|
||||||
|
racket/contract/base
|
||||||
|
racket/list
|
||||||
|
racket/async-channel
|
||||||
|
racket/system
|
||||||
|
ansi
|
||||||
|
(submod ansi/lcd-terminal event-structs)
|
||||||
|
ansi/private/tty-raw-extension
|
||||||
|
unix-signals
|
||||||
|
lux/chaos
|
||||||
|
raart/draw)
|
||||||
|
(provide (all-from-out (submod ansi/lcd-terminal event-structs)))
|
||||||
|
|
||||||
|
(struct term (f in out))
|
||||||
|
|
||||||
|
(define default-tty "/dev/tty")
|
||||||
|
|
||||||
|
#;
|
||||||
|
(define stty-minus-f-arg-string
|
||||||
|
(case (system-type 'os)
|
||||||
|
((macosx) "-f")
|
||||||
|
(else "-F")))
|
||||||
|
#;
|
||||||
|
(define (open-term #:tty [tty default-tty])
|
||||||
|
(system* "/bin/stty"
|
||||||
|
stty-minus-f-arg-string
|
||||||
|
tty
|
||||||
|
"raw"
|
||||||
|
"-echo")
|
||||||
|
(define-values (in out)
|
||||||
|
(open-input-output-file tty #:exists 'update))
|
||||||
|
(term tty in out))
|
||||||
|
#;
|
||||||
|
(define (close-term t)
|
||||||
|
(match-define (term f in out) t)
|
||||||
|
(close-input-port in)
|
||||||
|
(close-output-port out)
|
||||||
|
(system* "/bin/stty"
|
||||||
|
stty-minus-f-arg-string
|
||||||
|
f
|
||||||
|
"cooked"
|
||||||
|
"echo"))
|
||||||
|
|
||||||
|
(define (open-term)
|
||||||
|
(tty-raw!)
|
||||||
|
(term #f (current-input-port) (current-output-port)))
|
||||||
|
(define (close-term t)
|
||||||
|
(tty-restore!))
|
||||||
|
|
||||||
|
(define (with-term f #:tty [tty default-tty])
|
||||||
|
(define t (open-term #:tty tty))
|
||||||
|
(define (close!) (close-term t))
|
||||||
|
(with-handlers ([exn:fail? (λ (x) (close!) (raise x))])
|
||||||
|
(begin0 (f t) (close!))))
|
||||||
|
|
||||||
|
(define (display/flush v op)
|
||||||
|
(display v op)
|
||||||
|
(flush-output op))
|
||||||
|
|
||||||
|
(define (display/term t v)
|
||||||
|
(define op (term-out t))
|
||||||
|
(unless (port-closed? op)
|
||||||
|
(display/flush v op)))
|
||||||
|
|
||||||
|
;; Lux
|
||||||
|
(define x11-mouse-on
|
||||||
|
(string-append (set-mode x11-focus-event-mode)
|
||||||
|
(set-mode x11-any-event-mouse-tracking-mode)
|
||||||
|
(set-mode x11-extended-mouse-tracking-mode)))
|
||||||
|
(define x11-mouse-off
|
||||||
|
(string-append (reset-mode x11-extended-mouse-tracking-mode)
|
||||||
|
(reset-mode x11-any-event-mouse-tracking-mode)
|
||||||
|
(reset-mode x11-focus-event-mode)))
|
||||||
|
(define (make-raart #:alternate? [alternate? #f]
|
||||||
|
#:mouse? [mouse? #f])
|
||||||
|
(define t (open-term))
|
||||||
|
(define ch (make-async-channel))
|
||||||
|
;; Initialize term
|
||||||
|
(when alternate?
|
||||||
|
(display/term t (set-mode alternate-screen-mode)))
|
||||||
|
(when mouse?
|
||||||
|
(display/term t x11-mouse-on)
|
||||||
|
(plumber-add-flush! (current-plumber)
|
||||||
|
(lambda (handle)
|
||||||
|
(display/term t x11-mouse-off))))
|
||||||
|
;; Register for window change events
|
||||||
|
(display/term t (device-request-screen-size))
|
||||||
|
(capture-signal! 'SIGWINCH)
|
||||||
|
(define sig-th
|
||||||
|
(thread
|
||||||
|
(λ ()
|
||||||
|
(let loop ()
|
||||||
|
(define s (read-signal))
|
||||||
|
(match (lookup-signal-name s)
|
||||||
|
['SIGWINCH (display/term t (device-request-screen-size))
|
||||||
|
(loop)])))))
|
||||||
|
;; Listen for input
|
||||||
|
(define input-th
|
||||||
|
(thread
|
||||||
|
(λ ()
|
||||||
|
(let loop ()
|
||||||
|
(define v (lex-lcd-input (term-in t) #:utf-8? #t))
|
||||||
|
(unless (eof-object? v)
|
||||||
|
(async-channel-put ch v)
|
||||||
|
(loop))))))
|
||||||
|
;; Return
|
||||||
|
(*term alternate? mouse? t ch sig-th input-th 80 24))
|
||||||
|
|
||||||
|
(struct *term
|
||||||
|
(alternate? mouse? t ch sig-th input-th [rows #:mutable] [cols #:mutable])
|
||||||
|
#:methods gen:chaos
|
||||||
|
[(define (chaos-event c)
|
||||||
|
(handle-evt (*term-ch c)
|
||||||
|
(match-lambda
|
||||||
|
[(and e (screen-size-report rows cols))
|
||||||
|
(set-*term-rows! c rows)
|
||||||
|
(set-*term-cols! c cols)
|
||||||
|
e]
|
||||||
|
[e e])))
|
||||||
|
(define (chaos-output! c o)
|
||||||
|
(when o
|
||||||
|
(draw (crop 0 (*term-cols c)
|
||||||
|
0 (*term-rows c)
|
||||||
|
o)
|
||||||
|
#:output (term-out (*term-t c)))))
|
||||||
|
(define (chaos-label! c l)
|
||||||
|
(display/term (*term-t c) (xterm-set-window-title l)))
|
||||||
|
(define (chaos-stop! c)
|
||||||
|
(define t (*term-t c))
|
||||||
|
(when (*term-mouse? c)
|
||||||
|
(display/term t x11-mouse-off))
|
||||||
|
(when (*term-alternate? c)
|
||||||
|
(display/term t (reset-mode alternate-screen-mode)))
|
||||||
|
(kill-thread (*term-sig-th c))
|
||||||
|
(kill-thread (*term-input-th c))
|
||||||
|
(release-signal! 'SIGWINCH)
|
||||||
|
(close-term t))])
|
||||||
|
|
||||||
|
(provide
|
||||||
|
(contract-out
|
||||||
|
[make-raart
|
||||||
|
(->* () (#:alternate? boolean?) chaos?)]))
|
1
main.rkt
1
main.rkt
|
@ -1,2 +1,3 @@
|
||||||
#lang reprovide
|
#lang reprovide
|
||||||
"draw.rkt"
|
"draw.rkt"
|
||||||
|
"lux-chaos.rkt"
|
||||||
|
|
96
size.rkt
96
size.rkt
|
@ -1,92 +1,9 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
(require racket/match
|
|
||||||
racket/list
|
|
||||||
racket/system
|
|
||||||
ansi)
|
|
||||||
|
|
||||||
(define stty-minus-f-arg-string
|
;; xxx Do the rune thing as well (and think about mouse events)
|
||||||
(case (system-type 'os)
|
|
||||||
((macosx) "-f")
|
|
||||||
(else "-F")))
|
|
||||||
|
|
||||||
(define (read-until ip char)
|
;; xxx cool to support images (iterm2, urxvt, kitty, etc, but seem to
|
||||||
(define byte (char->integer char))
|
;; all be broken in tmux)
|
||||||
(apply bytes
|
|
||||||
(let loop ()
|
|
||||||
(match (read-byte ip)
|
|
||||||
[(== byte) empty]
|
|
||||||
[next (cons next (loop))]))))
|
|
||||||
|
|
||||||
(define (bytes->number bs)
|
|
||||||
(string->number (bytes->string/utf-8 bs)))
|
|
||||||
|
|
||||||
(define default-tty "/dev/tty")
|
|
||||||
(struct term (f in out))
|
|
||||||
(define (open-term #:tty [tty default-tty])
|
|
||||||
(system* "/bin/stty"
|
|
||||||
stty-minus-f-arg-string
|
|
||||||
tty
|
|
||||||
"raw"
|
|
||||||
"-echo")
|
|
||||||
(define-values (in out)
|
|
||||||
(open-input-output-file tty #:exists 'update))
|
|
||||||
(term tty in out))
|
|
||||||
|
|
||||||
(define (close-term t)
|
|
||||||
(match-define (term f in out) t)
|
|
||||||
(close-input-port in)
|
|
||||||
(close-output-port out)
|
|
||||||
(system* "/bin/stty"
|
|
||||||
stty-minus-f-arg-string
|
|
||||||
f
|
|
||||||
"cooked"
|
|
||||||
"echo"))
|
|
||||||
|
|
||||||
(define (with-term f #:tty [tty default-tty])
|
|
||||||
(define t (open-term #:tty tty))
|
|
||||||
(define (close!) (close-term t))
|
|
||||||
(with-handlers ([exn:fail? (λ (x) (close!) (raise x))])
|
|
||||||
(begin0 (f t) (close!))))
|
|
||||||
|
|
||||||
(define (with-term* t f)
|
|
||||||
(if t (f t) (with-term f)))
|
|
||||||
|
|
||||||
(define (screen-size [t #f])
|
|
||||||
(with-term* t
|
|
||||||
(λ (t)
|
|
||||||
(match-define (term _ in out) t)
|
|
||||||
(write-bytes #"\e[18t" out) (flush-output out)
|
|
||||||
(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))]
|
|
||||||
[x (error 'screen-size "Something weird happened, got ~e" x)]))))
|
|
||||||
|
|
||||||
(define (cursor-position [t #f])
|
|
||||||
(with-term* t
|
|
||||||
(λ (t)
|
|
||||||
(match-define (term _ in out) t)
|
|
||||||
(display (position-report-request) out) (flush-output out)
|
|
||||||
(match (read-bytes 2 in)
|
|
||||||
[#"\e["
|
|
||||||
(define row-s (read-until in #\;))
|
|
||||||
(define col-s (read-until in #\R))
|
|
||||||
(values (bytes->number row-s)
|
|
||||||
(bytes->number col-s))]
|
|
||||||
[x (error 'cursor-position "Something weird happened, got ~e" x)]))))
|
|
||||||
|
|
||||||
;; xxx xterm-set-window-title
|
|
||||||
#;(begin
|
|
||||||
(display (A:set-mode A:alternate-screen-mode))
|
|
||||||
(display (A:reset-mode A:alternate-screen-mode)))
|
|
||||||
|
|
||||||
;; xxx Do I make a 'lux chaos' for this?
|
|
||||||
;;
|
|
||||||
;; Or do I do the rune thing and make a separation between the
|
|
||||||
;; commands and the keys? Also, how should the mouse events fit
|
|
||||||
;; into that?
|
|
||||||
|
|
||||||
;; xxx render xexpr-like thing
|
;; xxx render xexpr-like thing
|
||||||
;; xxx text... (fit text inside a width)
|
;; xxx text... (fit text inside a width)
|
||||||
|
@ -95,8 +12,5 @@
|
||||||
;; xxx make a "Web" browser
|
;; xxx make a "Web" browser
|
||||||
;; xxx use if-drawn to figure out what links are on screen
|
;; xxx use if-drawn to figure out what links are on screen
|
||||||
|
|
||||||
(module+ main
|
;; xxx interactable thing --- figure out pos&dimensions on screen for
|
||||||
(with-term
|
;; supporting mouse
|
||||||
(λ (t)
|
|
||||||
(screen-size t)
|
|
||||||
(cursor-position t))))
|
|
||||||
|
|
Loading…
Reference in New Issue