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)))

Reply via email to