Hi Rainer,
On 4/17/07, Rainer Joswig joswig@lisp.de wrote:
I'm a bit used to the behavior of MCL when it comes to Lisp buffers and listeners. Maybe SLIME developers know how to achieve a similar behavior or would like to provide something similar.
MCL allowed multiple Lisp text editor windows and listener windows. If there are multiple listeners one is the front most.
SLIME does allow you to have multiple REPL windows. When you do "M-x slime" multiple times, it will ask you whether you want to create an additional repl.
If the cursor is behind a Lisp form in a Lisp editor window, one can press Enter (or control-return) and the form will be enqueued into the REPL of the front most listener. Doing this in a listener, the form will be displayed at the prompt and enqueued in the listener's REPL. Pressing Enter only has the effect that the form and the result is shown in the listener. In the Editor window, nothing happens (no cursor moved, no character entered, no window focus changed).
The listener REPL gets the forms from its queue and displays the form and the result at the end of the current buffer. This way you get interaction histories in the listener.
Currently SLIME lets me evaluate a form in a text buffer and the form gets printed into the listener and the result gets printed in the mini-buffer. I can see then in the listener the history of evaluated forms, but not the history of results. Additionally the form will be printed with additional characters before and after.
SLIME displays several forms evaluated from a text buffer in the REPL like this:
;;;; (+ 1 2) ... ;;;; (+ 1 2) ... ;;;; (+ 1 2) ...
The normal REPL interaction display would be like:
CL-USER> (+ 1 2) 3 CL-USER> (+ 1 2) 3 CL-USER> (+ 1 2) 3
Both ways look different. Why not use the latter for both interactions?
Useful is then also a command to rotate between the various listeners (next, previous) and Lisp buffers (next, previous).
Advantages I see for MCL:
- With MCL you get the same REPL listener display if you evaluate forms from
the Lisp editor buffer (via RETURN) or if you use the REPL in the listener.
- Using the enter key (vs. Return) to evaluate code in the editor gets rid of one complex keystroke.
- One gets reusable interaction histories in the listener where form and result are displayed together.
Is SLIME already providing something similar? Would others find this way of interaction between Lisp buffers and a REPL buffer useful?
I don't think SLIME provides this as a standard feature. However, I have a function that I use to do this. It sends to the repl buffer either the current highlighted region, or the sexp that is on/before the point, or the sexp that is on/after the point, or the top-level sexp (if the point is not on/before/after a paren). With a prefix arg, it will also press "Enter" in the repl so you don't have to press enter yourself. I frequently use the function when I'm doing presentations and want to step through code in a listener for the audience.
Here's the code with a sample binding of F9 (so use either F9 or C-u F9):
(defun slime-send-dwim (arg) "Send the appropriate forms to CL to be evaluated." (interactive "P") (save-excursion (cond ;;Region selected - evaluate region ((not (equal mark-active nil)) (copy-region-as-kill-nomark (mark) (point))) ;; At/before sexp - evaluate next sexp ((or (looking-at "\s(") (save-excursion (forward-char 1) (looking-at "\s("))) (forward-list 1) (let ((end (point)) (beg (save-excursion (backward-list 1) (point)))) (copy-region-as-kill-nomark beg end))) ;; At/after sexp - evaluate last sexp ((or (looking-at "\s)") (save-excursion (backward-char 1) (looking-at "\s)"))) (if (looking-at "\s)") (forward-char 1)) (let ((end (point)) (beg (save-excursion (backward-list 1) (point)))) (copy-region-as-kill-nomark beg end))) ;; Default - evaluate enclosing top-level sexp (t (progn (while (ignore-errors (progn (backward-up-list) t))) (forward-list 1) (let ((end (point)) (beg (save-excursion (backward-list 1) (point)))) (copy-region-as-kill-nomark beg end))))) (set-buffer (slime-output-buffer)) (unless (eq (current-buffer) (window-buffer)) (pop-to-buffer (current-buffer) t)) (goto-char (point-max)) (yank) (if arg (progn (slime-repl-return) (other-window 1)))))
(define-key lisp-mode-map [f9] 'slime-send-dwim)
-- Bill Clementson