Edit Files In A REPL
April 7, 2017
Many programming languages are interactive, with their primary interface a read-eval-print loop. Scheme is like that, so is Python, and so is the primary language I use in my day job, Oracle SQL*Plus, and so too are many other languages.
One feature many of those languages share is a way to edit files from the REPL. For instance, in SQL*Plus, the most recently-entered command is available in a buffer, and if you say “edit” the buffer will be loaded into whatever $EDITOR you specified, so you can modify the command as needed; when the editor returns, the modified buffer is then executed.
Although Scheme doesn’t provide such an editing feature, I have been using my own for years. It’s very simple, less than a dozen lines of code, and greatly enhances my productivity.
Your task is to write an editing interface for your favorite REPL. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
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. […]