Gosh's default REPL provides bare minimum features. I almost always run gosh inside Emacs and usually it's fine, but sometimes I do feel it can be better.
So I'm experimenting ideas here: http://gauche.svn.sourceforge.net/viewvc/gauche/Gauche-scripts/trunk/xrepl/
Here are some stuff I have. I'll use it for a while to see if it's worth to be included into gosh or not. Other ideas and feedbacks are welcome.
Prettyprinting the result
It has rudimental pretty printer (which is a bit dumb; it may take exponential time for large S-expr that I need to fix). Ideally pretty printer should be a part of Gauche, integrated with built-in format etc.
gosh> (call-with-input-string (values-ref (http-get "blog.practical-scheme.net" "/gauche") 2) (cut ssax:xml->sxml <> '())) (*TOP* (html (head (title "Gauche Devlog") (base (|@| (href "http://blog.practical-scheme.net/gauche"))) (link (|@| (type "application/rss+xml") (title "RSS") (rel "alternate") (href "http://blog.practical-scheme.net/gauche?c=rss"))) (link (|@| (type "text/css") (rel "stylesheet") (href "blog.css"))) (link (|@| (type "text/css") (rel "stylesheet") (href "gauche-devlog.css")))) (body ...
Accessing recent evaluation results. This feature has been sitting long in my wishlist, but I couldn't make up my mind of what symbols I would use; CL uses *, **, ***, ... but in Scheme * would conflict with the built-in function. I finally decided to adapt Clojure's convention; *1 refers to the last evaluated result, *2 for the second last, etc.
gosh> *1 (*TOP* (html (head (title "Gauche Devlog") ... gosh> (length (cadr *1)) 3
The procedure *history prints the list of history.
*1, *2, ... only keeps the first value of the result(s). In case if we have more than one values, *1+, *2+, ... keeps the list of values.
If the last evaluation ends as an error, the condition object is bound to *e.
gosh> (car 3) *** ERROR: pair required, but got 3 Stack Trace: _______________________________________ 0 (with-error-handler (lambda (e) (let ((e e)) (%guard-rec e e (else ... [unknown location] gosh> *e #<error "pair required, but got 3">
You can type shell commands by leading it with a comma:
gosh> ,cd ~/src/Gauche /home/shiro/src/Gauche gosh> ,ls AUTHORS README configure.ac ltmain.sh COPYING VERSION configure.ac.orig m4/ ChangeLog acinclude.m4 doc/ missing* DIST* aclocal.m4 examples/ mkinstalldirs* DIST_EXCLUDE config.guess* ext/ rpmfiles-common.txt Gauche.spec config.log framework.sh* rpmfiles-encoding.txt HACKING config.rpath* gc/ rpmfiles-gdbm.txt INSTALL.in config.status* gc.diff src/ Makefile config.sub* install-sh* test/ Makefile.in config.threads lib/ test.record NEWS configure* libsrc/ winnt/ gosh> ,make -j for d in gc src lib ext doc; do (cd $d; make all); done make: Entering directory `/home/shiro/src/Gauche/gc' ...
Sometimes I'm too lazy to switch from *scheme* buffer to *shell* buffer (or, more like that I forget to switch and am annoyed by getting 'unbound variable: ls').
It would be nicer if I can easily grab the shell output into Scheme variable, and feed the content of Scheme variable into shell commands.
Smarter (or verbose) error handling
I'm not sure I'll keep this one, but giving a try.
"." isn't in *load-path* by default, for the obvious security reasons. But sometimes I forget to type "./foo.scm" and being annoyed, for I know foo.scm in the current dir is safe. So, here's a little help...
gosh> (load "t.scm") *** REPL: Cannot load file "t.scm" in *load-path* ("../lib" "../libsrc" "../src" "/usr/share/gauche/site/lib" "/usr/share/gauche/0.9.1_pre1/lib" "/usr/share/gauche/0.9/lib" "/home/shiro/src/Gauche-scripts/xrepl/") But you have the file under the current directory. Do you want to add "." in *load-path*? (y/n):
This is actually implemented in more general "error filter" framework. When REPL gets an error, a series of registered tests are run, and if there's a match, an associated action is invoked.
This kind of thing may be too annoying (in fact, I don't even like CL implementations entering the debugger on error by default.) But I'll see.