Next: Conclusion, Previous: Embedder's API, Up: Hello Emacsy [Contents][Index]
Let’s exercise these functions in a minimal FreeGLUT program we’ll call hello-emacsy.4. This simple program will display an integer, the variable counter, that one can increment or decrement.
Hello Emacsy’s state is captured by one global variable. Hello Emacsy will display this number.
Initialize everything in main and enter our runloop.
Initialize GLUT.
Initialize Guile.
Initialize Emacsy.
Register primitives.
Try to load hello-emacsy.scm
Enter GLUT main loop, not return.
Let’s look at how Emacsy interacts with your application’s runloop since that’s probably the most concerning part of embedding. First, let’s pass some input to Emacsy.
Send key events to Emacsy.
int key; // The Key event (not processed yet).
The keys C-a and C-b return 1
and 2
respectively. We want to map these to their actual character values.
The function display_func is run for every frame that’s drawn. It’s effectively our runloop, even though the actual runloop is in FreeGLUT.
Our application has just one job: Display the counter variable.
Setup the display buffer the drawing.
Process events in Emacsy.
Display Emacsy message/echo area.
Display Emacsy mode line.
Draw a string function. Draws a string at (x, y) on the screen.
At this point, our application can process key events, accept input on the minibuffer, and use nearly all of the facilities that Emacsy offers, but it can’t change any application state, which makes it not very interesting yet.
Let’s define a new primitive Scheme procedure get-counter, so
Emacsy can access the application’s state. This will define
a C function SCM scm_get_counter (void)
and a Scheme procedure
(get-counter)
.
Let’s define another primitive Scheme procedure to alter the application’s state.
Once we have written these primitive procedures, we need to register them with the Scheme runtime.
Locate the hello-emacsy.scm Guile initialization and load it.
We generate the file example/hello-emacsy.c.x by running the
command: guile-snarf example/hello-emacsy.c
. Emacsy can now
access and alter the application’s internal state.
Bind inc-counter to =
.
Bind inc-counter to -
.
Let’s implement another command that will ask the user for a number to set the counter to.
Now we can hit M-x change-counter and we’ll be prompted for the new value we want. There we have it. We have made the simplest application ever more Emacs-y.
We can add commands easily by changing and reloading the file. But we can do better. Let’s start a REPL we can connect to. example/hello-emacsy.scm.
(use-modules (system repl server)) (spawn-server)
Start a server on port 37146.
Next: Conclusion, Previous: Embedder's API, Up: Hello Emacsy [Contents][Index]