---
layout: ../Site.layout.js
---
# Just draw an ellipse! Screwlisp's Common Lisp Interface Manager McCLIM intro
- - «.intro» (to "intro")
- - «.starting clim outside emacs» (to "starting clim outside emacs")
- - «.lisp class w ellipses list» (to "lisp class w ellipses list")
- - «.clim child of ellipses-mixin» (to "clim child of ellipses-mixin")
- - «.display-function» (to "display-function")
- - «.command random ellipse» (to "command random ellipse")
- - «.make ellipses frame» (to "make ellipses frame")
- - «.add one ellipse manually» (to "add one ellipse manually")
- - «.open the app» (to "open the app")
- - «.now disconnect emacs from lisp» (to "now disconnect emacs from lisp")
<img src="../just-an-ellipse.png">
## Intro
- - «intro» (to ".intro")
As I have said before, it is a bit of a misrepresentation of the common lisp interface manager spec to *just* draw an ellipse, though that is certainly very easy to do. Here is a very minimal application example though. We are of course using [JackDaniel](
https://turtleware.eu)'s [McCLIM](
https://codeberg.org/McCLIM/McCLIM/) implementation of the spec. In a gist, we are going to make a GUI application with a button that issues a command that adds a random ellipse, somewhat similar to my [cl-series-pure-lisp](/programming/cl-series-ellipse-sampling) one but using common lisp interface manager drawing equipment in a CLIM `application-frame` instead. Key features are the common lisp object system class integration and simply added interactive button, and threadsafe `execute-frame-command`.
As a quick note about historical context, while McCLIM hails originally from [Strandh](
https://metamodular.com/) in 1996, the clim spec was and is the modern progeny of lisp's/lisp machines' dynamic-windows from the 80s.
## Start our clim lisp image outside of emacs
- - «starting clim outside emacs» (to ".starting clim outside emacs")
Well, honestly inside emacs in this case, but it could have been outside of emacs. Starting lisp in a way emacs needs to explicitly separately connect to. I guess you [recognize this from over here](/momentary/eev-clim-kitten). And then `slime-connect`ing to the running common lisp image, that has McCLIM in it and started a swank server i.e. for emacs to connect to.
```
(eepitch-shell)
ecl
(require "asdf")
(asdf:load-system :mcclim)
(asdf:system-source-directory :swank)
(merge-pathnames #p"*.*" *)
(directory *)
(merge-pathnames #p"start-swank.lisp" **)
(load *)
(slime-connect "localhost" 4005)
(setq eepitch-buffer-name "*slime-repl ECL*")
(in-package :clim-user)
(print '(I can see this is working))
```
## Common Lisp class with a list of ellipses
- - «lisp class w ellipses list» (to ".lisp class w ellipses list")
```
(defclass ellipses-mixin () ((ellipses :initform '() :accessor ellipses)))
```
## CLIM `application-frame` child of that class
- - «clim child of ellipses-mixin» (to ".clim child of ellipses-mixin")
```
(define-application-frame ellipses-frame
(standard-application-frame ellipses-mixin) ()
(:pane :application :display-function 'draw-ellipses))
```
## Display-function
- - «display-function» (to ".display-function")
```
(defmethod draw-ellipses ((obj ellipses-frame) pane)
(loop :for ellipse :in (ellipses obj) :do
(apply 'draw-ellipse* pane ellipse)))
```
(The clim idiom is to `:incremental-redraw t .. updating-output` but that is its own kettle of fish. This is fine indicatively for now.)
## A command that adds a slightly random ellipse
- - «command random ellipse» (to ".command random ellipse")
```
(define-ellipses-frame-command
(com-add-random-ellipse :menu t :name t)
()
(let ((frame *application-frame*)
(ellipse (list (1+ (random #o200)) ; cx
(1+ (random #o200)) ; cy
(1+ (random #o200)) ; rdx1
(1+ (random #o200)) ; rdx2
(1+ (random #o200)) ; rdy1
(1+ (random #o200)) ; rdy2
)))
(push ellipse (ellipses frame))))
```
## Make one of these frames
- - «make ellipses frame» (to ".make ellipses frame")
```
(make-application-frame 'ellipses-frame)
(defparameter *ellipse-frame* *)
```
## Add one ellipse manually
- - «add one ellipse manually» (to ".add one ellipse manually")
```
(execute-frame-command *ellipse-frame* '(com-add-random-ellipse))
```
There is no special reason to do this except to see `execute-frame-command`. Note that anything that goes through `execute-frame-command` is threadsafe by McCLIM - super handy.
## Finally, open that app!
- - «open the app» (to ".open the app")
```
(run-frame-top-level *ellipse-frame*)
```
## Now quit lisp (`M-x sli-disc`) in emacs and go back to the image on its own
- - «now disconnect emacs from lisp» (to ".now disconnect emacs from lisp")
And reopen the frame from the 'external' lisp image
```
(eepitch-shell)
(in-package :clim-user)
(run-frame-top-level *ellipse-frame*)
```
Our ellipse and functionality introduced inside emacs is still there!
# Fin.
See you [on the Mastodon to talk about this example](
https://gamerplus.org/@screwlisp/114594982268789432) too everyone. If you need a push to get started especially. NOT SALTY AT ALL ABOUT MY EXPERIENCE REPORT ON MIXINS AND CLIM PRESENTATIONS BEING BETTER-LUCK-NEXT-YEAR'D BY ONE REVIEWER AT ELS2025 (thank-you for your notes).