Edit Files In A REPL
April 7, 2017
Here is my REPL editor, which is stored in file edfile.ss
and loaded when I start up my Scheme system:
(define-top-level-value '*editor* "ed") (define-top-level-value '*edfile* #f)
(define (ed . args) (if (pair? args) (set-top-level-value! '*edfile* (car args))) (if (not (top-level-value '*edfile*)) (error 'ed "file not found")) (system (string-append (top-level-value '*editor*) " " (top-level-value '*edfile*))) (load (top-level-value '*edfile*)))
This is specific to Chez Scheme, and is ugly because of the change in Scheme top-level semantics that was brought in with R6RS. The asterisks around the variable names are a Lisp convention; they are known colloquially as “earmuffs” and mark global variables. Here is a sample editing session, where I write a Sieve of Eratosthenes:
phil@haydn ~ $ scheme edfile.ss Chez Scheme Version 9.4.1 Copyright 1984-2016 Cisco Systems, Inc. > (ed "primes.ss") primes.ss: No such file or directory a (define (primes n) (let ((sieve (make-vector (+ n 1) #t))) (let loop ((p 2) (ps (list))) (cond ((< n p) (reverse ps)) ((vector-ref sieve p) (do ((i (* p p) (+ i p))) ((< n i)) (vector-set! siev i #f)) (loop (+ p 1) (cons p ps))) (else (loop (+ p 1) ps)))))) . wq 338 > (primes 50) Exception: variable siev is not bound Type (debug) to enter the debugger. > (ed) 338 /siev (let ((sieve (make-vector (+ n 1) #t))) // ((vector-ref sieve p) // (vector-set! siev i #f)) s//&e/p (vector-set! sieve i #f)) wq 339 > (primes 50) (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47) > (exit)
Yes, I really do use ed
. As you see above, it flows very nicely in an interactive session.
You can see the program at http://ideone.com/dWZveh.
Case-lambda would make this more readable, as well as providing better error checking. With its provision in R6RS and R7RS, I consider the manual style of handling multiple arguments obsolete. Let-optionals is even better if you have the original Shivers macro, but many implementations’ built-in versions are flaky, and the overhead can be high.
You might want to consider changing from ed(1) to ex(1), trading a little standardosity for added convenience. Auto-indentation during text entry is very nice once set up, and I often find infinite undo saves my bacon. The z command to page through a file is also very useful. Above all, in Lisp work I find it indispensable to be able to enter vi-mode just before I’m done and bounce on the % key to make sure all non-obvious parens are matched. The only vi-mode commands I need for this are h, j, k, l (cursor movement), a, i (what you expect), %, and Q or gQ to return to ex-mode.
@JohnCowan: I didn’t realize that
case-lambda
became part of the standard in R6RS. I’ll use it from now on.Although I didn’t show it in the exercise, for my own use I actually have two functions,
(ed ...)
and(vi ...)
, that share a common*edfile*
but hardcode the name of the editor, and use whichever makes sense at the time. If I want to useex
I call it fromvi
. I normally useed
for simple editing, andvi
for bigger edits. I generally prefered
, except for very large edits, because I find the switch from line-mode in the REPL to screen-mode in the editor distracting. I do usevi
when I get a mis-matched parenthesis error, as you do; maybe I will add an(ex ...)
function to my toolbox for that purpose.I’ve always had a soft spot in my heart for
ed
, as it was the first editor I learned on Unix, more years ago than I care to admit. Long liveed
![…] Documentation of the Standard Prelude is provided on the web page noted above. I defer to Chez Scheme for hash tables, structures and random numbers, rather than using the versions in my Standard Prelude, and also defer to Chez Scheme for the Standard Prelude functions that Chez Scheme provides natively. The only part of the Standard Prelude that is not loaded is avl trees, which are removed to their own library. Also loaded at each run of Chez Scheme are my literate programming environment described at https://programmingpraxis.com/2010/08/10/literate-programming and my interactive editing environment described at https://programmingpraxis.com/2017/04/07/edit-files-in-a-repl. […]