Next: Expect, Previous: Value History, Up: Top
You can run a Guile interpreter as a subprocess under Emacs in many ways. One way is to type M-x shell RET and invoke Guile from the resulting shell. Another is to type C-u M-x run-scheme RET and specify guile as the scheme program name. See Shell, for details.
This chapter documents yet another way, which makes use of an experimental, low-level, custom protocol between Emacs and the Guile subprocess.
On the Guile side of things, the protocol is activated by evaluating the form:
(use-modules (ice-9 emacs))
Note that Guile does this for you if given the --emacs command-line
option (see Invoking Guile).
On the Emacs side of things, M-x inferior-guile RET handles the
lowest-level protocol details, including starting a Guile subprocess, passing
the --emacs command-line option to it, and arranging to filter the
subprocess output into state transitions (see below). To make this
command available, place in your .emacs file the forms:
(require 'add-guile-dirs)
(require 'inf-guile)
The low-level details of the protocol are “internal”, and (despite years of neglect) are subject to change in the future. So this section concentrates on the abstract model presented to the Emacs side of the things:
:hello:enter-input-wait:exit-input-wait:enter-read-character:sending-error:sending-backtrace:sending-result:end-of-text:no-stack:no-source:state:output-so-farnil, leading up to this
transition. Note that the string may be empty.
Handlers are funcalled directly without any type or error checking. See Process Information.
As you can surmise from the preceding section, any user-friendly (or even
user-visible :-) behavior must be implemented by specifying state transition
handler functions. You do this with define-inf-guile-transition:
This arranges for handler to be called when the Guile subprocess goes from state from to state to. from or to may be
tto indicate “any” state.
For any transition, the handler called is searched first with exact from
and to, then with exact from and any to, then with any
from and exact to and finally, with any from and any
to. This latter transition is the default transition, which is
pre-set to call inf-guile-null-transition.
This function does nothing, and is the handler for the default transition.
An example of using the programming interface described above is distributed with Guile. To play, evaluate the forms in Emacs:
(require 'add-guile-dirs)
(require 'inf-guile-synch-voeb)
This will make inf-guile-synchronous-send/return available. Here is
a sample session (snapshot from the *scratch* buffer) using it:
(setq p (inferior-guile))
⇒ #<process inferior guile>
(defun p! (s &rest args)
(apply 'inf-guile-synchronous-send/return
p s args))
⇒ p!
(p! "42")
⇒ ["42
" nil nil]
(dolist (x (number-sequence 1 3))
(p! "(define (add-%d n) (+ %d n))" x x))
⇒ nil
(p! "add-3")
⇒ ["#<procedure add-3 (n)>
" nil nil]
(p! "(add-3 (* 3 13))")
⇒ ["42
" nil nil]
(p! "(add-2 #:nope!)")
⇒ ["ABORT: (wrong-type-arg)
" "ERROR: In procedure + in expression (+ 2 n):
ERROR: Wrong type argument: #:nope!
" "
Backtrace:
0* [add-2 #:nope!]
1 [+ 2 #:nope!]
"]
(p! "(quit)")
⇒ [nil nil nil]
Note that inf-guile-synchronous-send/return returns a “vector of
output, error-message and backtrace-message”, which might help to explain the
contraction “voeb”. Also, with the exception of the last call to p!,
the output string (first element in the vector) always includes a newline.