Skip to content

Commit

Permalink
add Readme, misc cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
3b committed Jul 7, 2010
1 parent cbbf391 commit 15fc8e5
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 72 deletions.
57 changes: 57 additions & 0 deletions Readme.md
@@ -0,0 +1,57 @@
### Slime proxy

A hack for using slime with things like parenscript and 3bil that
compile code on a host lisp then run it somewhere else.

Currently only usable with parenscript, using websockets for
communication between host lisp and browser.

#### Requirements:
* currently only works on sbcl, since clws hasn't been ported to other lisps yet
* [modified parenscript](http://github.com/3b/parenscript)
* [clws](http://github.com/3b/clws)
* [websockets emulation](http://github.com/gimite/web-socket-js) for browsers without native support
* misc libraries: ironclad, anaphora, cl-ppcre, yason

#### Loading:

load slime-proxy/slime-proxy.el into emacs, then `M-x eval-buffer`

load/start proxy stuff (listens on port 12345 by default, adjust in wsproxy.lisp if needed)

(require 'slime-proxy)
(swank-proxy-ws::start-proxy-server)
(swank::create-proxy-listener)

adjust URLs in slime-proxy/slimy.html

`/wsjs/*` → files from web-socket-js

`ws://127.0.0.1:12345/` → host/port to use to connect to websocket serrver, if changed

(if clients are loading page from somewhere other than localhost, add the host to the `(ws:origin-prefix "http..." ...)` form in wsproxy,lisp)

load slimy.html in browser

switch an emacs buffer to proxy mode:
`M-: (setq slime-proxy-proxy-connection t) RET`
or

;;; -*- Mode: LISP; slime-proxy-proxy-connection: t -*-




#### things that (mostly) work
* compile/eval with `C-c C-c`, `C-c C-k`, `M-C-x`, `C-x C-e` and REPL
* non-autodoc arglist display (including introspecting from browser if possible)
* `M-.`
* connection to multiple browsers at once (currently just sends
everything to all connected browsers, so can behave a bit oddly.
seems like it might be useful enough to try to figure out how to
make it work sanely though)

#### things that don't work
* autodoc
* debugger
* pretty much everything else :p
54 changes: 54 additions & 0 deletions autodoc.lisp
@@ -0,0 +1,54 @@
(in-package #:swank)


(defun ps-arglist-dispatch (op args)
(declare (ignorable args))
#++(let ((*package* (find-package :keyword)))
(format t "p-a-d ~s ~s~%" op args)
)
(when (ps::parenscript-function-p op)
;(format t "p-a-d -> ~s~%" (ps::parenscript-arglist op))
(with-available-arglist (decoded-arglist)
(decode-arglist (ps::parenscript-arglist op))
#++(enrich-decoded-arglist-with-extra-keywords decoded-arglist
(cons op args))
(values decoded-arglist nil nil))))

;;;; autodoc hooks
;;fixme: separate this into a separate file, only load with autodoc contrib
(defmethod arglist-dispatch :around (op argument)
;(format t "arglist dispatch ~s / ~s~T" op argument)
(when (next-method-p)
(call-next-method))
#++((ps::parenscript-function-p sym)
(let ((args (ps::parenscript-arglist sym)))
(format t "found s function, args=~s~%" args)
(cond ((eq args :not-available) nil)
(t (princ-to-string (cons name args))))))
)


(defmethod arglist-dispatch :around (op argument)
; (format t "arglist dispatch ~s / ~s~T" op argument)
(when (next-method-p)
(call-next-method))
#++((ps::parenscript-function-p sym)
(let ((args (ps::parenscript-arglist sym)))
(format t "found s function, args=~s~%" args)
(cond ((eq args :not-available) nil)
(t (princ-to-string (cons name args))))))
)

(defmethod arglist-dispatch (operator arguments)
;(format t "--dispatch--~%")
(cond
((and (symbolp operator) (valid-operator-symbol-p operator))
(multiple-value-bind (decoded-arglist determining-args)
(compute-enriched-decoded-arglist operator arguments)
(with-available-arglist (arglist) decoded-arglist
;; replace some formal args by determining actual args
(setf arglist (delete-given-args arglist determining-args))
(setf (arglist.provided-args arglist) determining-args)
arglist)))
((find-if (lambda (hook) #++(format t "trying hook ~s~%" hook) (funcall hook operator arguments)) *arglist-dispatch-hooks*))
(t (return-from arglist-dispatch :not-available))))
8 changes: 8 additions & 0 deletions slimy.html
Expand Up @@ -19,6 +19,11 @@

// Set URL of your WebSocketMain.swf here:
WebSocket.__swfLocation = "/wsjs/WebSocketMain.swf";
WebSocket.__debug = true;
// for newer versions of web-socket-js
WEB_SOCKET_SWF_LOCATION = "/wsjs/WebSocketMain.swf";
// Set this to dump debug message from Flash to console.log:
WEB_SOCKET_DEBUG = true;

var ws;
var count = 0;
Expand Down Expand Up @@ -61,6 +66,9 @@
ws.onclose = function() {
output("onclose");
};
ws.onerror = function() {
output("onerror");
};

}

Expand Down
63 changes: 7 additions & 56 deletions swank-proxy.lisp
Expand Up @@ -3,19 +3,10 @@
(defclass proxy-channel (channel)
()
)
(defun ps-arglist-dispatch (op args)
(declare (ignorable args))
#++(let ((*package* (find-package :keyword)))
(format t "p-a-d ~s ~s~%" op args)
)
(when (ps::parenscript-function-p op)
;(format t "p-a-d -> ~s~%" (ps::parenscript-arglist op))
(with-available-arglist (decoded-arglist)
(decode-arglist (ps::parenscript-arglist op))
#++(enrich-decoded-arglist-with-extra-keywords decoded-arglist
(cons op args))
(values decoded-arglist nil nil))))

;; stub out some stuff that otherwise would require a hacked slime
(defvar *arglist-dispatch-hooks* nil)
(defvar *operator-p-hooks* nil)
(defun ps-operator-p (op )
#++(let ((*package* (find-package :keyword)))
(format t "operator-p ~s = ~s~%" op (ps::parenscript-function-p op)))
Expand All @@ -42,7 +33,7 @@
(cond
((ps::parenscript-function-p sym)
(let ((args (ps::parenscript-arglist sym)))
(format t "found s function, args=~s~%" args)
#++(format t "found ps function, args=~s~%" args)
(cond ((eq args :not-available) nil)
(t (princ-to-string (cons name args))))))
;; then ask a browser
Expand Down Expand Up @@ -126,8 +117,8 @@
(swank-backend:buffer-first-change (eval name)))
((swank:find-definitions-for-emacs name)
(let ((n (from-string (eval name)) ))
(format t "looking for xrefs for ~s = ~s (p ~s~%~%" name n *package*)
(print (gethash n ps::*ps-function-location-toplevel-cache*)))
#++(format t "looking for xrefs for ~s = ~s (p ~s~%~%" name n *package*)
(gethash n ps::*ps-function-location-toplevel-cache*))
#++(print (swank:find-definitions-for-emacs "defun")))
((swank:autodoc raw-form &key print-right-margin)
(swank:autodoc (eval raw-form) :print-right-margin (eval print-right-margin) ))
Expand Down Expand Up @@ -199,7 +190,7 @@
(setf *channels* '())
(setf *channel-counter* 0)
(create-proxy-listener))

#++
(create-proxy-listener)

;;; eval-and-grab-output
Expand All @@ -209,43 +200,3 @@
;;; listener-eval
;;; completions



;;;; autodoc hooks
;;fixme: separate this into a separate file, only load with autodoc contrib
(defmethod arglist-dispatch :around (op argument)
;(format t "arglist dispatch ~s / ~s~T" op argument)
(when (next-method-p)
(call-next-method))
#++((ps::parenscript-function-p sym)
(let ((args (ps::parenscript-arglist sym)))
(format t "found s function, args=~s~%" args)
(cond ((eq args :not-available) nil)
(t (princ-to-string (cons name args))))))
)


(defmethod arglist-dispatch :around (op argument)
; (format t "arglist dispatch ~s / ~s~T" op argument)
(when (next-method-p)
(call-next-method))
#++((ps::parenscript-function-p sym)
(let ((args (ps::parenscript-arglist sym)))
(format t "found s function, args=~s~%" args)
(cond ((eq args :not-available) nil)
(t (princ-to-string (cons name args))))))
)

(defmethod arglist-dispatch (operator arguments)
;(format t "--dispatch--~%")
(cond
((and (symbolp operator) (valid-operator-symbol-p operator))
(multiple-value-bind (decoded-arglist determining-args)
(compute-enriched-decoded-arglist operator arguments)
(with-available-arglist (arglist) decoded-arglist
;; replace some formal args by determining actual args
(setf arglist (delete-given-args arglist determining-args))
(setf (arglist.provided-args arglist) determining-args)
arglist)))
((find-if (lambda (hook) #++(format t "trying hook ~s~%" hook) (funcall hook operator arguments)) *arglist-dispatch-hooks*))
(t (return-from arglist-dispatch :not-available))))
5 changes: 3 additions & 2 deletions test.lisp
@@ -1,3 +1,4 @@
;;; -*- Mode: LISP; slime-proxy-proxy-connection: t -*-
(in-package :proxy-test)

(list 1 () 1)
Expand All @@ -15,8 +16,8 @@
(@ navigator app-code-name)

((@ canvas get-context) )
((@ document get-element-by-id) )
((@ swfobject register-object) )
((@ document get-element-by-id))
((@ swfobject register-object) )
((@ ((@ document get-element-by-id ) "canvas") get-context) )

(alert "foo1")
Expand Down
27 changes: 13 additions & 14 deletions wsproxy.lisp
Expand Up @@ -92,20 +92,19 @@
#++
(run-swank-proxy-server)

;; entry point for buildapp deployment
#++
(defun main (argv)
(declare (ignore argv))
(sb-thread:make-thread
(lambda ()
(ws::run-server 12345))
:name "socket server")

(sb-thread:make-thread
(lambda ()
(run-swank-proxy-server))
:name "resource handler")
(sb-impl::toplevel-repl nil))
(defun start-proxy-server ()
(let ((con swank::*emacs-connection*))
(sb-thread:make-thread
(lambda ()
(let ((swank::*emacs-connection* con))
(ws::run-server 12345)))
:name "socket server")

(sb-thread:make-thread
(lambda ()
(let ((swank::*emacs-connection* con))
(run-swank-proxy-server)))
:name "resource handler")))

#++
(defun swank (&key (dont-close nil))
Expand Down

0 comments on commit 15fc8e5

Please sign in to comment.