[Top][All Lists]

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

Guile + Emacs HOWTO

From: Andy Wingo
Subject: Guile + Emacs HOWTO
Date: Fri, 15 Feb 2008 15:43:00 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.50 (gnu/linux)

Greetings conniving guilers,

Today I figured out some awesomeness: how to hook up Emacs to a running
Guile application. Good times! Directions follow, after a bit of

 1) Install guile-debugging. If you are running HEAD guile, you already
    have it installed, because it is part of Guile. Otherwise if you are
    running 1.6 or 1.8, it's a little bit hacky:

    # Check out Guile HEAD:
        cvs -z3 -d:pserver:address@hidden:/sources/guile \
            co -d guile-HEAD guile/guile-core
    # Copy (ice-9 debugging) to a suitable location:
        sudo mkdir -p /usr/share/guile/site/ice-9
        sudo cp -r guile-HEAD/ice-9/debugging /usr/share/guile/site/ice-9
    # Copy (ice-9 gds-client) and (ice-9 gds-server) there too:
        sudo cp -r guile-HEAD/ice-9/gds-* /usr/share/guile/site/ice-9
    # Install the emacs foo:
        sudo mkdir -p ~/.emacs-el/
        sudo cp -r guile-HEAD/emacs/gds*.el ~/.emacs-el.

    (Alternately you can download and install the guile-debugging 0.15
    tarball, but its gds-scheme.el file is slightly out of date relative
    to the one in Guile CVS.)

 2) In Emacs, load up GDS by adding:
        (require 'gds)
    to your ~/.emacs. If you had to follow the manual installation steps
    of (1), you'll want to add ~/.emacs-el to the load path via:
        (add-to-list 'load-path "~/.emacs-el/")
    Put the `add-to-list' before the `require'.

 3) Verify that GDS is working. Open /tmp/foo.scm, type (+ 2 2), and
    press C-x C-e. It should start a guile process, evaluate the
    expression, and print out the answer. Yay!

So now the obvious question is, how do I get Emacs to do this with a
running process, like a web server? Well, it turns out this is easy
enough. However you should know something about the architecture of GDS,
Guile's Emacs integration library.

              | Emacs                    |
              | running gds-server.el    |
              | guile running            |
              | (ice-9 gds-server)       |
               /---        \-
   +---------------+   +-----\-----------+
   |guile running  |   |another guile    |  more guiles...
   |(ice-9 gds-client) |running gds-client
   +---------------+   +-----------------+

All of the boxes in this diagram are processes, and all of them connect
to the gds server, which conventionally runs on port 8333. Indeed,
(ice-9 gds-client) has no way to specify another port -- something to
fix, I guess. The GDS server serves as a kind of multiplexing point
between emacsen and guiles, although I do not thing the multiple-emacs
thing works yet. By default, and currenty the only way to do things,
Emacs will start gds-server as needed, or explicitly via M-x

When you pressed C-x C-e before in the foo.scm buffer, what happened was
that Emacs saw that the buffer was not yet associated with any guile
process, so Emacs started a guile process itself. The client process was
spawned by emacs exactly like this:

  guile -c '(begin (use-modules (ice-9 gds-client)) (run-utility))'

`run-utility' is named that way because it was made for emacs to run a
"utility guile process", an anonymous process in which to evaluate guile
things. However the code is generic, you can call this in your own
application, and voici the point of this email.

In your application, just run the following:

   (use-modules (ice-9 gds-client) (ice-9 threads))
   (make-thread run-utility)

and then go about your business. A separate thread will be spawned for
interacting with emacs. Of course, your guile will have to support
threads, and I don't think that Debian's 1.8 does. In that case you
might want to add a --gds-debug option to your application so that
instead of going into whatever other main loop it would go into, that it
goes into the run-utility loop. Or just compile a threaded guile.

Then, inside emacs, associate your buffers with that guile:

  M-x gds-associate-buffer
  [choose the PID of your guile process]

At that point you can start evaluating code inside emacs and having it
update in the live application, interactively deal with backtraces,
inspect the stack, set breakpoints, etc. Fun stuff.

Happy hacking!


reply via email to

[Prev in Thread] Current Thread [Next in Thread]