--- layout: ../Site.layout.js --- # Emacs eev and common lisp McCLIM - - «.aside» (to "aside") - - «.outside emacs» (to "outside emacs") - - «.inside emacs» (to "inside emacs") - - «.clim-user» (to "clim-user") - - «.defining an application-frame» (to "defining an application-frame") - - «.making a frame» (to "making a frame") - - «.starting a frame» (to "starting a frame") - - «.in the gui» (to "in the gui") - - «.after killing emacs» (to "after killing emacs") - - «.fin» (to "fin") I have a particular fantasy idiom for using McCLIM inside emacs. Since McCLIM uses a swank server, and a swank server handles multiple connections, we can start McCLIM outside of emacs, then slime-connect emacs to that external server. The fantasy aspect is that our creations from inside emacs will survive `kill-emacs` in the external lisp image, which can be hooked into again by a later emacs. It's a nascent idea. - [McCLIM on Codeberg](https://codeberg.org/McCLIM/McCLIM/) - [Jackdaniel's lisp blog](https://turtleware.eu/) - [The Common Lisp Interface Manager CLIM II specification](http://bauhh.dyndns.org:8000/clim-spec/index.html) - [Franz' (proprietary implementation) reference documentation](https://franz.com/support/documentation/8.1/doc/clim-ug.pdf) - [Lispworks' (proprietary implementation) reference documentation](https://www.lispworks.com/documentation/lw80/clim/clim.htm) ## Aside - Franz Inc open sourced their CLIM 2 in 2016? - - «aside» (to ".aside") I found it while looking up links. On github though! - [https://github.com/craigl64/clim2](https://github.com/craigl64/clim2) ## Strictly outside of emacs - - «outside emacs» (to ".outside emacs") and inside your shell, I guess. This is not for eev (I guess it would work in `(eepitch-shell)` but that would be *inside* emacs). ``` ecl (require "asdf") (asdf:load-system :mcclim) (asdf:system-source-directory :swank) (merge-pathnames #p"start-swank.lisp" *) (load *) ``` ## Strictly inside of emacs - connect to mcclim's swank - - «inside emacs» (to ".inside emacs") Now we are happily using `eev` `eepitch`. ```  (eepitch-shell)  (eepitch-kill)  (slime-connect "localhost" 4005)  (setq eepitch-buffer-name "*slime-repl ECL*") ``` Remember that we loaded `mcclim` already in the external lisp. ## `eepitch` into `clim-user` - - «clim-user» (to ".clim-user") In lisp, we often make `-user` packages to absorb user code. This user package is what the package developer expects their users to basically experience. ``` (in-package :clim-user) ``` ## Defining an `application-frame` - - «defining an application-frame» (to ".defining an application-frame") ``` (define-application-frame gui () ()) ``` ## Make one particular `gui` `application-frame` - - «making a frame» (to ".making a frame") We don't have to instantiate it and can just `find-application-frame` to pull it up headlessly, but we want it to stick around outside of emacs in this case. ``` (make-application-frame 'gui) (defparameter *gui* *) ``` ## Start it. - - «starting a frame» (to ".starting a frame") ``` (run-frame-top-level *gui*) ``` ## In the gui that just popped up - - «in the gui» (to ".in the gui") The default interactor is a simple shell (having I guess `Help`, `Describe` and `Quit`). Note that it has autocompletion and emacs-like cut and paste. The autocompletion is used implicitly. If you are filling out a form, `` will set the current field and move to the next one, `C-g` aborts, and `M-` (alt+enter) sends the form. ## Cannot *simply* `kill-emacs` and leave the form running - - «after killing emacs» (to ".after killing emacs") I guess I would need to start it in another thread in a tricky way. Still, we can easily pop up a gui now. And that `*gui*` still literally exists in the running `ECL` lisp image outside of emacs. # Fin. - - «fin» (to ".fin") So the `*gui*` does not *do* anything yet, but what we did works and it persists outside of the emacs session. See you [on the Mastodon to talk about this](https://screwlisp.small-web.org).