Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn't automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs , reader macro characters aren't evaluated until a matching ] has been found.
"Seth Burleigh" seth@tewebs.com writes:
Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn?t automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs , reader macro characters aren?t evaluated until a matching ] has been found.
That's because command line REPL uses READ directly. It's possible to make slime's repl to do the same, but i don't think it's feasible.
On Dec 31, 2009, at 7:45 AM, Seth Burleigh wrote:
Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn’t automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs, reader macro characters aren’t evaluated until a matching ] has been found.
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Below is the minor required modification of swank. It assumes that the client uses #'swank:listener-eval to evaluate a string from the listener in the repl. I have implemented the functionality in MCLIDE and verified that it works. The small change on the client was a simplification as it no longer has to determine where a lisp form ends.
===========================================
(defun eval-region (string) "Evaluate STRING. Return the results of the last form as a list and as secondary value the last form, with third value indicating the index of the first character not read in STRING" (with-input-from-string (stream string) (let (- values) (loop (let* ((index (file-position stream)) (form (handler-case (read stream nil stream) (end-of-file () (finish-output) (return (values values - index)))))) (when (eq form stream) (finish-output) (return (values values -))) (setq - form) (setq values (multiple-value-list (eval form))) (finish-output))))))
(defun repl-eval (string) (clear-user-input) (with-buffer-syntax () (with-retry-restart (:msg "Retry SLIME REPL evaluation request.") (track-package (lambda () (multiple-value-bind (values last-form index) (eval-region string) (setq *** ** ** * * (car values) /// // // / / values +++ ++ ++ + + last-form) (unless index (funcall *send-repl-results-function* values)) index))))))
===================================
-- Terje Norderhaug terje@in-progress.com
On Dec 31, 2009, at 9:23 PM, Terje Norderhaug wrote:
On Dec 31, 2009, at 7:45 AM, Seth Burleigh wrote:
Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn’t automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs, reader macro characters aren’t evaluated until a matching ] has been found.
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Below is the minor required modification of swank.
Here are the changes:
diff -u slime-2009-12-31/swank.lisp slime-2009-12-31+/swank.lisp --- slime-2009-12-31/swank.lisp 2009-12-23 00:15:03.000000000 -0800 +++ slime-2009-12-31+/swank.lisp 2009-12-31 21:43:45.000000000 -0800 @@ -2213,11 +2213,16 @@ (defun eval-region (string) "Evaluate STRING. Return the results of the last form as a list and as secondary value the -last form." +last form, with third value indicating the index of the first character not read in STRING" (with-input-from-string (stream string) (let (- values) (loop - (let ((form (read stream nil stream))) + (let* ((index (file-position stream)) + (form (handler-case + (read stream nil stream) + (end-of-file () + (finish-output) + (return (values values - index)))))) (when (eq form stream) (finish-output) (return (values values -))) @@ -2293,12 +2298,13 @@ (with-retry-restart (:msg "Retry SLIME REPL evaluation request.") (track-package (lambda () - (multiple-value-bind (values last-form) (eval-region string) + (multiple-value-bind (values last-form index) (eval-region string) (setq *** ** ** * * (car values) /// // // / / values +++ ++ ++ + + last-form) - (funcall *send-repl-results-function* values)))))) - nil) + (unless index + (funcall *send-repl-results-function* values)) + index))))))
-- Terje Norderhaug terje@in-progress.com
It doesn't appear to work when I use clisp. When I define the macros like this (set-macro-character #[ (lambda (stream char) (read-delimited-list #] stream t))) (set-macro-character #] (get-macro-character #)))
And go [print And then press enter it states 'error in process filter: wrong type arguments: listp,0 Then when I press enter again it returns ; no value Or I enter , say , 'a it'll return 'a.
Im using the first code you posted.
-----Original Message----- From: Terje Norderhaug [mailto:terje@in-progress.com] Sent: Thursday, December 31, 2009 11:47 PM To: slime-devel@common-lisp.net Subject: Re: [slime-devel] Readtables
On Dec 31, 2009, at 9:23 PM, Terje Norderhaug wrote:
On Dec 31, 2009, at 7:45 AM, Seth Burleigh wrote:
Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn't automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs, reader macro characters aren't evaluated until a matching ] has been found.
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Below is the minor required modification of swank.
Here are the changes:
diff -u slime-2009-12-31/swank.lisp slime-2009-12-31+/swank.lisp --- slime-2009-12-31/swank.lisp 2009-12-23 00:15:03.000000000 -0800 +++ slime-2009-12-31+/swank.lisp 2009-12-31 21:43:45.000000000 -0800 @@ -2213,11 +2213,16 @@ (defun eval-region (string) "Evaluate STRING. Return the results of the last form as a list and as secondary value the -last form." +last form, with third value indicating the index of the first character not read in STRING" (with-input-from-string (stream string) (let (- values) (loop - (let ((form (read stream nil stream))) + (let* ((index (file-position stream)) + (form (handler-case + (read stream nil stream) + (end-of-file () + (finish-output) + (return (values values - index)))))) (when (eq form stream) (finish-output) (return (values values -))) @@ -2293,12 +2298,13 @@ (with-retry-restart (:msg "Retry SLIME REPL evaluation request.") (track-package (lambda () - (multiple-value-bind (values last-form) (eval-region string) + (multiple-value-bind (values last-form index) (eval-region string) (setq *** ** ** * * (car values) /// // // / / values +++ ++ ++ + + last-form) - (funcall *send-repl-results-function* values)))))) - nil) + (unless index + (funcall *send-repl-results-function* values)) + index))))))
-- Terje Norderhaug terje@in-progress.com
_______________________________________________ slime-devel site list slime-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/slime-devel
On Jan 1, 2010, at 4:16 AM, Seth Burleigh wrote:
It doesn't appear to work when I use clisp. When I define the macros like this (set-macro-character #[ (lambda (stream char) (read-delimited-list #] stream t))) (set-macro-character #] (get-macro-character #)))
And go [print And then press enter it states 'error in process filter: wrong type arguments: listp,0 Then when I press enter again it returns ; no value Or I enter , say , 'a it'll return 'a.
Im using the first code you posted.
The code requires that SLIME implements the client side of the functionality.
I have already implemented it for the MCLIDE client as proof of concept. Let me know if you want to try it out.
I found it actually resulted in a simplification of the client code as the swank server takes the responsibility for determining the end of expressions in the listener.
-- Terje
-----Original Message----- From: Terje Norderhaug [mailto:terje@in-progress.com] Sent: Thursday, December 31, 2009 11:47 PM To: slime-devel@common-lisp.net Subject: Re: [slime-devel] Readtables
On Dec 31, 2009, at 9:23 PM, Terje Norderhaug wrote:
On Dec 31, 2009, at 7:45 AM, Seth Burleigh wrote:
Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn't automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs, reader macro characters aren't evaluated until a matching ] has been found.
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Below is the minor required modification of swank.
Here are the changes:
diff -u slime-2009-12-31/swank.lisp slime-2009-12-31+/swank.lisp --- slime-2009-12-31/swank.lisp 2009-12-23 00:15:03.000000000 -0800 +++ slime-2009-12-31+/swank.lisp 2009-12-31 21:43:45.000000000 -0800 @@ -2213,11 +2213,16 @@ (defun eval-region (string) "Evaluate STRING. Return the results of the last form as a list and as secondary value the -last form." +last form, with third value indicating the index of the first character not read in STRING" (with-input-from-string (stream string) (let (- values) (loop
(let ((form (read stream nil stream)))
(let* ((index (file-position stream))
(form (handler-case
(read stream nil stream)
(end-of-file ()
(finish-output)
(return (values values - index)))))) (when (eq form stream) (finish-output) (return (values values -)))
@@ -2293,12 +2298,13 @@ (with-retry-restart (:msg "Retry SLIME REPL evaluation request.") (track-package (lambda ()
(multiple-value-bind (values last-form) (eval-region string)
(multiple-value-bind (values last-form index) (eval-region
string) (setq *** ** ** * * (car values) /// // // / / values +++ ++ ++ + + last-form)
(funcall *send-repl-results-function* values))))))
- nil)
(unless index
(funcall *send-repl-results-function* values))
index))))))
-- Terje Norderhaug terje@in-progress.com
slime-devel site list slime-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/slime-devel
slime-devel site list slime-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/slime-devel
-- Terje Norderhaug terje@in-progress.com
I've now decided im just going to redefine the open parentheses macro so I guess I wont be needing this. Still, in the future, it would be great if slime included this! Thanks again!
-----Original Message----- From: Terje Norderhaug [mailto:terje@in-progress.com] Sent: Friday, January 01, 2010 10:16 AM To: slime-devel@common-lisp.net Subject: Re: [slime-devel] Readtables
On Jan 1, 2010, at 4:16 AM, Seth Burleigh wrote:
It doesn't appear to work when I use clisp. When I define the macros like this (set-macro-character #[ (lambda (stream char) (read-delimited-list #] stream t))) (set-macro-character #] (get-macro-character #)))
And go [print And then press enter it states 'error in process filter: wrong type arguments: listp,0 Then when I press enter again it returns ; no value Or I enter , say , 'a it'll return 'a.
Im using the first code you posted.
The code requires that SLIME implements the client side of the functionality.
I have already implemented it for the MCLIDE client as proof of concept. Let me know if you want to try it out.
I found it actually resulted in a simplification of the client code as the swank server takes the responsibility for determining the end of expressions in the listener.
-- Terje
-----Original Message----- From: Terje Norderhaug [mailto:terje@in-progress.com] Sent: Thursday, December 31, 2009 11:47 PM To: slime-devel@common-lisp.net Subject: Re: [slime-devel] Readtables
On Dec 31, 2009, at 9:23 PM, Terje Norderhaug wrote:
On Dec 31, 2009, at 7:45 AM, Seth Burleigh wrote:
Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn't automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs, reader macro characters aren't evaluated until a matching ] has been found.
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Below is the minor required modification of swank.
Here are the changes:
diff -u slime-2009-12-31/swank.lisp slime-2009-12-31+/swank.lisp --- slime-2009-12-31/swank.lisp 2009-12-23 00:15:03.000000000 -0800 +++ slime-2009-12-31+/swank.lisp 2009-12-31 21:43:45.000000000 -0800 @@ -2213,11 +2213,16 @@ (defun eval-region (string) "Evaluate STRING. Return the results of the last form as a list and as secondary value the -last form." +last form, with third value indicating the index of the first character not read in STRING" (with-input-from-string (stream string) (let (- values) (loop
(let ((form (read stream nil stream)))
(let* ((index (file-position stream))
(form (handler-case
(read stream nil stream)
(end-of-file ()
(finish-output)
(return (values values - index)))))) (when (eq form stream) (finish-output) (return (values values -)))
@@ -2293,12 +2298,13 @@ (with-retry-restart (:msg "Retry SLIME REPL evaluation request.") (track-package (lambda ()
(multiple-value-bind (values last-form) (eval-region string)
(multiple-value-bind (values last-form index) (eval-region
string) (setq *** ** ** * * (car values) /// // // / / values +++ ++ ++ + + last-form)
(funcall *send-repl-results-function* values))))))
- nil)
(unless index
(funcall *send-repl-results-function* values))
index))))))
-- Terje Norderhaug terje@in-progress.com
slime-devel site list slime-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/slime-devel
slime-devel site list slime-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/slime-devel
-- Terje Norderhaug terje@in-progress.com
_______________________________________________ slime-devel site list slime-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/slime-devel
On Jan 2, 2010, at 9:33 AM, Seth Burleigh wrote:
it would be great if slime included this!
Yes, this small change to the code would be very beneficial far beyond the specific situation you brought up. It will provide better support for evaluating "unconventional" expressions in the Listener, such as custom reader macros, microlanguages, and other dialects of Lisp such as Clojure. I am in favor of moving ahead with it asap.
-- Terje Norderhaug terje@in-progress.com
-----Original Message----- From: Terje Norderhaug [mailto:terje@in-progress.com] Sent: Friday, January 01, 2010 10:16 AM To: slime-devel@common-lisp.net Subject: Re: [slime-devel] Readtables
On Jan 1, 2010, at 4:16 AM, Seth Burleigh wrote:
It doesn't appear to work when I use clisp. When I define the macros like this (set-macro-character #[ (lambda (stream char) (read-delimited-list #] stream t))) (set-macro-character #] (get-macro-character #)))
And go [print And then press enter it states 'error in process filter: wrong type arguments: listp,0 Then when I press enter again it returns ; no value Or I enter , say , 'a it'll return 'a.
Im using the first code you posted.
The code requires that SLIME implements the client side of the functionality.
I have already implemented it for the MCLIDE client as proof of concept. Let me know if you want to try it out.
I found it actually resulted in a simplification of the client code as the swank server takes the responsibility for determining the end of expressions in the listener.
-- Terje
-----Original Message----- From: Terje Norderhaug [mailto:terje@in-progress.com] Sent: Thursday, December 31, 2009 11:47 PM To: slime-devel@common-lisp.net Subject: Re: [slime-devel] Readtables
On Dec 31, 2009, at 9:23 PM, Terje Norderhaug wrote:
On Dec 31, 2009, at 7:45 AM, Seth Burleigh wrote:
Is there any current support for having the REPL respect reader macro characters? For example, if I define the [] pair to act like parentheses the repl shouldn't automatically send a multiline [ ] form to lisp until a matching ] has been found. On command line REPLs, reader macro characters aren't evaluated until a matching ] has been found.
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Below is the minor required modification of swank.
Here are the changes:
diff -u slime-2009-12-31/swank.lisp slime-2009-12-31+/swank.lisp --- slime-2009-12-31/swank.lisp 2009-12-23 00:15:03.000000000 -0800 +++ slime-2009-12-31+/swank.lisp 2009-12-31 21:43:45.000000000 -0800 @@ -2213,11 +2213,16 @@ (defun eval-region (string) "Evaluate STRING. Return the results of the last form as a list and as secondary value the -last form." +last form, with third value indicating the index of the first character not read in STRING" (with-input-from-string (stream string) (let (- values) (loop
(let ((form (read stream nil stream)))
(let* ((index (file-position stream))
(form (handler-case
(read stream nil stream)
(end-of-file ()
(finish-output)
(return (values values - index)))))) (when (eq form stream) (finish-output) (return (values values -)))
@@ -2293,12 +2298,13 @@ (with-retry-restart (:msg "Retry SLIME REPL evaluation request.") (track-package (lambda ()
(multiple-value-bind (values last-form) (eval-region
string)
(multiple-value-bind (values last-form index) (eval-region
string) (setq *** ** ** * * (car values) /// // // / / values +++ ++ ++ + + last-form)
(funcall *send-repl-results-function* values))))))
- nil)
(unless index
(funcall *send-repl-results-function* values))
index))))))
* Terje Norderhaug [2010-01-01 06:23+0100] writes:
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Nice idea. But there are still problems with reader macros. E.g. input like
(progn #.(print 'foo) <RET> )
would print FOO twice. If you want to add this kind of state to the protocol it might be easier to make the REPL read from a custom stream. The stream informs Emacs when more input is requested. The REPL in turn tells Emacs when to print results and prompts.
Helmut
On Jan 5, 2010, at 1:23 AM, Helmut Eller wrote:
- Terje Norderhaug [2010-01-01 06:23+0100] writes:
One way to have the REPL respect reader macro characters is by making evaluation on swank return the index of the first character not read, with the client using this as the starting position for the next read.
Nice idea. But there are still problems with reader macros. E.g. input like
(progn #.(print 'foo) <RET> )
would print FOO twice.
Yes, this idea assumes that reader macros don't have side effects besides the reading from the stream.
Fortunately X3J13 comes to the rescue. According to the Hyperspec:
"The reader macro function must not have any side effects other than on the input stream; because of backtracking and restarting of the read operation, front ends to the Lisp reader (e.g., ``editors'' and ``rubout handlers'') may cause the reader macro function to be called repeatedly during the reading of a single expression in which x only appears once."
http://www.lispworks.com/documentation/HyperSpec/Body/02_b.htm
If you want to add this kind of state to the protocol it might be easier to make the REPL read from a custom stream. The stream informs Emacs when more input is requested. The REPL in turn tells Emacs when to print results and prompts.
I agree that using a stream and maintaining REPL state would be a beneficial upgrade, perhaps as a next step. Particularly as it is hard to enforce the prohibition on side effects for CL reader macros, but also as other lisp dialects may not require side effect free reader macros.
-- Terje Norderhaug terje@in-progress.com