Giter VIP home page Giter VIP logo

swank-client's Introduction

Swank Client

Swank Client is a Common Lisp implementation of the client side of the Swank debugging protocol used by Slime, a GNU Emacs mode that implements an IDE for Lisp programming. Emacs uses the Swank protocol to communicate with a Lisp system when a user runs the IDE, but the protocol is useful independently of Emacs because it allows a client to evaluate expressions on a remote Lisp that's running a Swank server.

Swank Client is used by Swank Crew to implement a Slime IDE for developing distributed algorithms in Lisp.

The Swank Client API

slime-connect host-name port &optional connection-closed-hook

Connects to the Swank server running on HOST-NAME that is listening on PORT.
Returns a SWANK-CONNECTION if the connection attempt is successful.  Otherwise,
returns NIL.  May signal SLIME-NETWORK-ERROR if the user has a Slime secret
file and there are network problems sending its contents to the remote Swank
server.  If provided, function CONNECTION-CLOSED-HOOK is called when the
connection is closed.

slime-close connection

Closes CONNECTION to a Swank server.

slime-eval sexp connection

Sends SEXP over CONNECTION to a Swank server for evaluation and waits for the
result.  When the result is received, it is returned.  Signals
SLIME-NETWORK-ERROR when there are network problems sending SEXP.

slime-eval-async sexp connection &optional continuation

Sends SEXP over CONNECTION to a Swank server for evaluation, then immediately
returns.  Some time later, after the evaluation is finished, CONTINUATION is
called with the result as argument.  Signals SLIME-NETWORK-ERROR when there are
network problems sending SEXP.

slime-migrate-evals old-connection new-connection

Evaluates on NEW-CONNECTION all the work pending on a closed OLD-CONNECTION.
Signals SLIME-NETWORK-ERROR when there are network problems.

slime-pending-evals-p connection

Returns T if there are outstanding evaluations pending on CONNECTION;
otherwise, returns NIL.

with-slime-connection (variable host-name port &optional connection-closed-hook) &body body

Wraps BODY in a LET form where VARIABLE is bound to the value returned by
(SLIME-CONNECT HOST-NAME PORT CONNECTION-CLOSED-HOOK).  Arranges for the Swank
connection to be closed when control exits BODY.

For more information, see the documentation strings in swank-client.lisp and the example code in swank-client-test.lisp.

Swank Client example

Starting a Swank server

The code below starts two Swank servers, one listening on port 4005 and the other listening on port 10000.

(load-quicklisp)
(asdf:load-system 'com.google.base)
(asdf:load-system 'swank)

(defvar *emacs-port* 4005)
(defvar *swank-client-port* 10000)

(defun swank-thread ()
  "Returns a thread that's acting as a Swank server."
  (dolist (thread (sb-thread:list-all-threads))
    (when (com.google.base:prefixp "Swank" (sb-thread:thread-name thread))
      (return thread))))

(defun wait-for-swank-thread ()
  "Wait for the Swank server thread to exit."
  (let ((swank-thread (swank-thread)))
    (when swank-thread
      (sb-thread:join-thread swank-thread))))

(defun main ()
  (setf swank:*configure-emacs-indentation* nil
        swank::*enable-event-history* nil
        swank:*log-events* t)
  (swank:create-server :port *emacs-port* :dont-close t)
  (swank:create-server :port *swank-client-port* :dont-close t)
  (wait-for-swank-thread))

(main)

Using Swank Client to evaluate an expression on the server

Once the Swank servers are running, you can connect to the server on port 4005 from Emacs using the command M-x slime-connect. This connection is a normal Slime IDE session. From the Slime IDE you can evaluate the following code, which creates a Swank Client connection to the server running on port 10000 and remotely evaluates the expression (cons 1 2).

(load-quicklisp)
(asdf:load-system 'swank-client)

(swank-client:with-slime-connection (connection "localhost" 10000)
  (swank-client:slime-eval '(cons 1 2) connection))

swank-client's People

Contributors

brown avatar jcguu95 avatar sfreilich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swank-client's Issues

Would you consider a more permissive license?

This library would be very useful for me. And I know I'm being selfish in asking this, but would you be open to a more permissive license? My end goal is to use it in a commercial application (binary built with LispWorks).

I completely understand if that's not something you want to do though. Just wanted to make sure your choice of GPL was intentional.

REPEAT inside LOOP

change
0b3bd89

moved the REPEAT inside LOOP to the end, but that contradicts the CL standard in
http://www.lispworks.com/documentation/HyperSpec/Body/06_aba.htm
which states:
"The iteration control clauses for, as, and repeat must precede any other loop clauses, except initially, with, and named, since they establish variable bindings"

The first paragraph of the desciption of termination test clauses http://www.lispworks.com/documentation/HyperSpec/Body/06_ad.htm also impliess that REPEAT needs to be in the prolog.

This doesn't fit with the syntax of LOOP in:
http://www.lispworks.com/documentation/HyperSpec/Body/m_loop.htm

but it actually makes more sense, because the form of REPEAT is evaluated only once, and if it returns 0 the body of the LOOP form is not evaluated.

LispWorks gives an error for the REPEAT in the end.

Putting the REPEAT after the FOR but before the body match both definitions, so probably the best approach.

                 (loop for i from 2  repeat +server-count+ collect i)

And actually, even better would be:

               (loop for i from 2  below (+ 2  +server-count+) collect i)

Because this has only one counter.

Prior work

I implemented a swank-client for Common Lisp many years ago as part of the now defunct MCLIDE project. Perhaps parts can be of use:

https://github.com/njordhov/mclide/tree/master/mclide/src/swank-client

You have my permission to take whatever you like from the sources. Attribution is optional.

A key insight from my development is that the transportation protocol can be shared between the client and server, using the same code on both sides. I successfully lobbied to factor it out into the rpc module in swank.

The value is not of type `SWANK::MULTITHREADED-CONNECTION`

I'm testing swank-client in a minimal setting. To reproduce the error, open two sbcl in two separate terminals. In the first repl, enter the following

(ql:quickload :swank)
(swank:create-server :port 9000 :dont-close t)
(defvar *y* 7)
(in-package :cl)
(defvar *y* 8)

Good. No errors. Now I'm going to connect to this repl using swank-client from the second repl. So in the second repl, enter the following

(ql:quickload :swank-client)
(in-package :swank-client)
(defvar *c* (slime-connect "localhost" 9000))
(slime-eval '(+ 1 1) *c*)

No errors, with the last form returns 2 as expected. Enter the real test: (slime-eval '*y* *c*), and it returns an error

debugger invoked on a TYPE-ERROR in thread
#<THREAD "swank dispatcher for localhost/9000" RUNNING {1004448373}>:
  The value
    NIL
  is not of type
    SWANK::MULTITHREADED-CONNECTION

The current thread is not at the foreground,
SB-THREAD:RELEASE-FOREGROUND has to be called in #<SB-THREAD:THREAD "main thread" RUNNING {1001568103}>
for this thread to enter the debugger.

The repl then hangs there without returning to the prompt.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.