#lang syndicate ;;; SPDX-License-Identifier: LGPL-3.0-or-later ;;; SPDX-FileCopyrightText: Copyright © 2021-2024 Tony Garnock-Jones (module+ main (require racket/cmdline) (require (only-in racket/port read-line-evt)) (require syndicate/drivers/tcp) (require syndicate/drivers/racket-event) (define host "127.0.0.1") (define port 5999) (command-line #:once-each [("--host" "-H") hostname "Set hostname to connect to" (set! host hostname)] [("--port" "-p") port-number "Set port number to connect to" (set! port (string->number port-number))]) (standard-actor-system (ds) (with-services [syndicate/drivers/racket-event] (establish-connection ds (TcpRemote host port) #:initial-mode (Mode-lines (LineMode-lf)) #:on-connect (lambda (source sink) (at ds (on (message (RacketEvent (read-line-evt (current-input-port)) $vs)) (match (car vs) [(? eof-object?) (stop-current-facet (log-info "EOF on stdin."))] [line (send-line sink line)])))) #:on-rejected (lambda (message) (stop-current-facet (log-error "~a" message))) #:on-disconnect (lambda () (stop-current-facet (log-info "Disconnected"))) #:on-data (lambda (line _mode) ;; \e7 DECSC, save cursor position ;; \n\e[A Force a new line if at end of screen, then back up; effect of \r ;; \e[L Insert a line here, pushing the current line's contents down one ;; ~a Placeholder for the incoming line ;; \e8 DECRC, Restore cursor - it will be one line too high ;; \e[B Correct for the one line to high (printf "\e7\n\e[A\e[L~a\e8\e[B" line) (flush-output))))))