Hi All,
I wanted to know is it possible in slime/swank to evaluate elisp code from lisp environment.
Basically I need to do it in StumpWM(sbcl) environment, currently I am doing it through `emacs -e _form_' command and then prepending a quote at the start of output and then evaluating it in current lisp environment.
Sharad Pratap sh4r4d@gmail.com writes:
Hi All,
I wanted to know is it possible in slime/swank to evaluate elisp code from lisp environment.
Basically I need to do it in StumpWM(sbcl) environment, currently I am doing it through `emacs -e _form_' command and then prepending a quote at the start of output and then evaluating it in current lisp environment.
Look at swank::eval-in-emacs.
Thanks for valuable information about swank::eval-in-emacs
I tried it in scratch slime and output I am able to get in message buffer.
But if I am running it in Stumpwm process with stumpwm eval command, where I have started swank server, I am not able to get output, the error I am pasting.
-------------------------------------------------------------------------------------------- 18:22:23 Outputting a message: *The value NIL is not of type SWANK::CONNECTION.0: \ (SB-DEBUG::MAP-BACKTRACE #<CLOSURE (LAMBDA #) {B799655}>)[:EXTERNAL] 1: (SB-DEBUG:BACKTRACE 100 #<SB-IMPL::STRING-OUTPUT-STREAM {B799601}>) 2: (STUMPWM::BACKTRACE-STRING) 3: (ERR "^B^1*~A")[:EXTERNAL] 4: (STUMPWM::EVAL-LINE "(swank::eval-in-emacs '(message "sdfsdgdfg"))") 5: (STUMPWM::CALL-INTERACTIVELY "eval" #S(STUMPWM::ARGUMENT-LINE :STRING "eval" :START 5)) 6: (STUMPWM::EVAL-COMMAND "eval" T) 7: ((LABELS #:G300) :CODE 49 :STATE 4) 8: (STUMPWM::HANDLE-EVENT)[:EXTERNAL] 9: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK)) 10: ((FLET #:WITHOUT-INTERRUPTS-BODY-[CALL-WITH-RECURSIVE-LOCK]291)) 11: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #<CLOSURE (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK) {B797DCF5}> #S(SB-THREAD:MUTEX :NAME "CLX Event Lock" :%OWNER #<SB-THREAD:THREAD "initial thread" RUNNING {B475649}> :STATE 1)) 12: (XLIB:PROCESS-EVENT #<XLIB:DISPLAY :0 (The X.Org Foundation R10706000)>)[:EXTERNAL] 13: (STUMPWM::STUMPWM-INTERNAL-LOOP) 14: (STUMPWM::STUMPWM-INTERNAL ":0") 15: (STUMPWM ":0") 16: ((LAMBDA ())) 17: ((LABELS SB-IMPL::RESTART-LISP)) --------------------------------------------------------------------------------------------
I have started the swank server here by this way -------------------------------------------------------------------------------------------- (swank:create-server :port 4005 :style swank:*communication-style* :dont-close t) --------------------------------------------------------------------------------------------
then connected slime in emacs with it.
-- Regards, -sharad
Sharad Pratap sh4r4d@gmail.com writes:
I wanted to know is it possible in slime/swank to evaluate elisp code from lisp environment.
Basically I need to do it in StumpWM(sbcl) environment, currently I am doing it through `emacs -e _form_' command and then prepending a quote at the start of output and then evaluating it in current lisp environment.
Yes, of course.
This worked with slime a few years ago. I don't know if it still works. ------------------------------------------------------------------------ ;;;; emacs <-> common-lisp RPC with slime/swank
;;; In emacs, we can execute Common Lisp expressions:
(require 'slime)
(slime)
(setf slime-enable-evaluate-in-emacs t)
(defun eval-in-cl (cl-expression-string process-result-values) (slime-eval-with-transcript `(swank:eval-and-grab-output ,cl-expression-string) (lexical-let ((here (current-buffer)) (process-result-values process-result-values)) (lambda (result-values) (set-buffer here) (funcall process-result-values result-values)))))
(eval-in-cl "(values 1 * (ext:! 20) (package-name *package*))" (lambda (values) (dolist (v values) (insert (format "%s\n" v))))) ;; Returns: ;; ;; nil ;; ;; then later inserts: ;; ;; 1 ;; (42 (EMACS-UNREADABLE |buffer| |*scratch*|)) ;; 2432902008176640000 ;; "COMMON-LISP-USER"
;;; In Common Lisp, we can execute emacs lisp expressions:
(defparameter *emacs-readtable* (copy-readtable)) (setf (readtable-case *emacs-readtable*) :preserve) (set-syntax-from-char #> #) *emacs-readtable*) (set-dispatch-macro-character ## #< (lambda (stream subchar dispchar) `(emacs-unreadable ,@(read-delimited-list #> stream t))) *emacs-readtable*)
;; Probably more readtable patching would be in order. ;; ;; We could define CLOS proxies for emacs objects for a more seamless ;; integration. swank::eval-in-emacs process the CL form to make it ;; "emacs" (eg. downcase symbols, etc). It could convert CLOS proxies ;; to emacs lisp forms returning the corresponding emacs object.
(defun eval-in-emacs (form &optional nowait) (let ((result (SWANK::EVAL-IN-EMACS `(format "%S" ,form) nowait)) (*readtable* *emacs-readtable*)) (with-input-from-string (in result) (let ((result (read in nil in))) result))))
(eval-in-emacs `(progn (switch-to-buffer (buffer-named "*scratch*")) (goto-char (point-max)) (insert ,(format nil "~%Hello~%")) (list 42 (current-buffer))))
;; Switch to the *scratch* buffer, ;; goto the last position, and ;; inserts \nHello\n ;; then returns: ;; (42 (EMACS-UNREADABLE |buffer| |*scratch*|))
------------------------------------------------------------------------