[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [spr4653] using the cl-emacs connection



Try this out.  The following code assumes Allegro CL 4.1, which was
just released a week ago.

On the emacs side, define the following functions:

   ;;;; ED-WAIT

   (defun ed-quit ()
     (interactive)
     (fi::pop-metadot-session))

   ;;;; ED-SEXP

   (defun lep::edit-form (form)
     (switch-to-buffer (get-buffer-create "*ed*"))
     (erase-buffer)
     (insert (prin1-to-string form))
     (goto-char (point-min))
     (setq buffer-file-name "/tmp/foo.cl")
     (fi:common-lisp-mode))

   ;;;; ED-SEXP-WAIT

   (defvar lep::ed-sexp-wait-session nil)

   (defun lep::edit-string-wait (string)
     (setq lep::ed-sexp-wait-session session)
     (switch-to-buffer (get-buffer-create "*ed*"))
     (erase-buffer)
     (insert string)
     (goto-char (point-min))
     (setq buffer-file-name "/tmp/foo.cl")
     (fi:common-lisp-mode)
     (define-key (current-local-map) "\C-c\C-c" 'ed-sexp-wait-done))

   (defun ed-sexp-wait-done ()
     (interactive)
     (lep-send-reply lep::ed-sexp-wait-session (buffer-string))
     (setq lep::ed-sexp-wait-session nil)
     (bury-buffer))

   ;;; The following function should be defined in the emacs-lisp interface,
   ;;; but it didn't make it into the ACL 4.1 release.

   (defun lep-send-reply (session string)
     (let* ((connection (fi::session-connection session))
	    (process (fi::connection-process connection)))
       (send-string process
		    (prin1-to-string
		     (list (fi::session-id session) ':reply string)))
       (send-string process "\n")))

On the lisp side define the following functions:

   (in-package :lep)

   ;;;; ED-WAIT

   (defun ed-wait (symbol)
     (let ((process (make-session nil 'metadot-session
				  :fspec symbol
				  :lisp-initiated-p t)))
       (mp:process-wait "for ED-WAIT to complete"
			#'(lambda (process)
			    (null (mp:process-stack-group process)))
			process)))

   ;;;; ED-SEXP

   (define-query ed-sexp-query (form) (simple-query)
     (:replyp t)
     ("lep::edit-form" form))

   (defun ed-sexp (form)
     (ed-sexp-query :form form))

   ;;;; ED-SEXP-WAIT

   (defun ed-sexp-wait (form)
     (let* ((string (with-output-to-string (s)
		      (write form :stream s :pretty t)))
	    (new-string
	     (wait-for-reply (ed-sexp-wait-1 :string string))))
       (values (read-from-string new-string))))

   (define-query ed-sexp-wait-1 (string) (simple-query)
     (:oncep nil)
     ("lep::edit-string-wait" string))

Here is a sample usage:

user(14): (lep::ed-sexp-wait '(foo bar))
 >>> right here, the *ed* buffer popped up and I added `baz' to the
 >>> end of the list, then typed C-cC-c.  Then, lep::ed-sexp-wait returned:
(foo bar baz)

user(15): 



Obviously the expressions send to emacs can't have unprintable objects
(ones printed like #<...>) in them, but other than that, it should
work fine.

Hope this helps.

Kevin Layer, Franz Inc.         1995 University Avenue, Suite 275
layer@Franz.COM (internet)      Berkeley, CA  94704  USA
Phone: (510) 548-3600           FAX: (510) 548-8253