I have started to recreate something simple, old and reliable from scratch:
it's about creating VI (thats vi and not a roman 6) as a Guile/GOOPS
implementation with full Scheme support and it's going to replace Emacs
for me in the long run.
I start out with Unicode C0 (http://unicode.org/charts/PDF/U0000.pdf)
formerly known as ASCII. I had a look at JTextComponent, GtkTextView,
NSTextField and the Athena Widget Set Ascii/Text routines as well as
XTerm. I decided to start with the terminal view/shell and to keep in
mind the requisites of a graphical user interface for later extension.
For this I have written a preliminary GOOPS class terminal (<terminal>)
which is attached for those interested having a look at.
I'm not really used to the method by generic approach and I do not have
much experience with feature rich implementations in GOOPS. I don't know
how it will scale or how compatible it will be with the rest of Guile.
But please don't tell me to use nCurses because it's written in C and
today's virtual terminals are already well behaved, I guess.
I'm not seeking help here but advice and wish list entries. Comments and
ideas are welcome as well.
(use-modules (oop goops))
;;
;; Pretext
;;
(define (repeat n closure)
"Execute closure n times."
(if (not (and (exact? n)
(integer? n) ; 'integer?' does not check for exactness ...
(>= n 0)))
(error "repeat: the parameter n must be an exact natural number or zero.")
(let loop ((i 0))
(if (< i n)
(begin
(closure)
(loop (1+ i)))) )))
;;
;; Terminal
;;
(define-class <terminal> ()
;; XXX guarantee rw access to the device
(port #:init-value #f
#:accessor get-port
#:init-keyword #:port))
(define-method (control (terminal <terminal>) control-characters)
(display (list->string control-characters) (get-port terminal)))
(define-method (full-reset (terminal <terminal>))
(control terminal '(#\esc #\c)))
;;
;; Control Sequence Introduction
(define CSI '(#\esc #\[))
;;
;; SRM: Send Receive Mode
;; turn terminal echo on or off
(define-method (SRM-echo-off (terminal <terminal>))
(control terminal (append CSI '(#\1 #\2 #\h))))
(define-method (SRM-echo-on (terminal <terminal>))
(control terminal (append CSI '(#\1 #\2 #\l))))
;;
;; CSI: Cursor Control
(define-method (cursor-up (terminal <terminal>))
(control terminal (append CSI '(#\A))))
(define-method (cursor-down (terminal <terminal>))
(control terminal (append CSI '(#\B))))
(define-method (cursor-forward (terminal <terminal>))
(control terminal (append CSI '(#\C))))
(define-method (cursor-backward (terminal <terminal>))
(control terminal (append CSI '(#\D))))
;;
;; si-nUI0 - test case
(define term (make <terminal> #:port (current-output-port)))
(full-reset term)
(display "Hallo World! This is si-nUI0.")
(repeat 15 (lambda () (cursor-down term)))
(repeat 20 (lambda () (cursor-forward term)))