Or see the list of project sponsors.
Documentation | 🥺 |
Docstrings | 😀 |
Tests | 😀 |
Examples | 😀 |
RepositoryActivity | 🥺 |
CI | 😀 |
Lime is a standalone SWANK client. It can be used to programmatically connect to the SWANK server without Emacs.
One useful thing, you might do is to make a command-line client to send a command to your server. One practical task is code hot-reload. Here is an example of how to implement it using another SWANK client.
Example from Lime's sources shows how to create a REPL connected to the SWANK. However, this example creates a SWANK server in the same process. I think it will be more realistic to connect from one lisp to another.
So, I modified example to make it connect to the localhost 20100, where we'll start a separate ClozureCL process with SWANK:
Clozure Common Lisp Version 1.12 (v1.12) DarwinX8664
For more information about CCL, please see http://ccl.clozure.com.
CCL is free software. It is distributed under the terms of the Apache
Licence, Version 2.0.
? (ql:quickload :swank)
To load "swank":
Load 1 ASDF system:
swank
; Loading "swank"
? (swank:create-server :port 20100 :dont-close t :style :spawn)
;; Swank started at port: 20100.
20100
Now we need a function which will make a connection and provide us with the remote REPL.
I just removed the code which starts SWANK in the same process and replaced (uiop:hostname)
with "localhost", because (uiop:hostname)
didn't work for me:
POFTHEDAY> (defun repl ()
"Start the REPL."
(let ((conn (lime:make-connection "localhost"
20100)))
(lime:connect conn)
(format t "Swank server running on ~A ~A~%"
(lime:connection-implementation-name conn)
(lime:connection-implementation-version conn))
(loop
;; Read all events
(sleep 0.05)
(let ((events (lime:pull-all-events conn)))
(loop for event in events do
(typecase event
(lime:write-string-event
(write-string (lime:event-string event)))
(lime:debugger-event
(write-string "Entered debugger!"))
(t
t))))
;; Take input
(if (lime:connection-reader-waiting-p conn)
;; Read a line to send as standard input
(progn
(format t "~%Read: ")
(let ((input (read-line)))
(lime:send-input conn input)))
;; Read regular code
(progn
(format t "~A> " (lime:connection-package conn))
(let ((input (read)))
(lime:evaluate conn
(with-standard-io-syntax
(prin1-to-string input)))))))))
Now we can connect to our ClozureCL process and have a fun!
;; We are connecting from SBCL to CCL
POFTHEDAY> (lisp-implementation-type)
"SBCL"
POFTHEDAY> (lisp-implementation-version)
"2.0.2"
POFTHEDAY> (repl)
Swank server running on ccl Version 1.12 (v1.12) DarwinX8664
COMMON-LISP-USER> (lisp-implementation-type)
"Clozure Common Lisp"
COMMON-LISP-USER> (lisp-implementation-version)
"Version 1.12 (v1.12) DarwinX8664"
COMMON-LISP-USER> (+ 1 2)
3
If you are going to try Lime
on CCL, use the patched swank-protocol
system with this fix. Without the fix Lime will not work because of the following error:
<INFO> [23:48:47] swank-protocol swank-protocol.lisp (read-message) -
Read message SWANK-PROTOCOL::RESULT: (:READER-ERROR
"(:emacs-rex (swank-repl:listener-eval #A((7) common-lisp:base-char . \"(+ 1 2)\")) \"COMMON-LISP-USER\" :repl-thread 5)
"
"Reader error on #<STRING-INPUT-STREAM :CLOSED #x30200139FB9D>:
reader macro #A used without a rank integer")
I experienced the same error with Lem editor. And it was fixed with a similar patch.