clojure and clojurescript in org-babel
Table of Contents
1 Clojure and Clojurescript in Org-Babel
TLDR: your org-directory
needs to have a project.clj
for lein
and Clojure
, and a deps.edn
and dev.cljs.edn
for Clojurescript
.
Note: this is specifically for doom emacs, but should work on other emacs’ as well. This is partially based off the official docs, but has been extended to work with the clj
tool as well as lein
. I use lein
for clojure
and clj
for clojurescript
. Clojurescript
through cider should also pop open a browser, which you should be able to interact with from your org file, using figwheel
.
I had attempted using clojupyter and other jupyter solutions, but they were all so complicated to install that I stuck with this current version. I had also attempted ob-clojurescript
, but this simply directly evaluated src
blocks as opposed to sending them to the repl, which is my desired behaviour. My hope is to do exploratory programming and learn while using the repl, while also taking notes and documenting the process. So here’s how to get it set up:
1.1 Installation
We assume we have set org-directory
like so. This is the root directory of where you will be writing your org
files that will have executable clojure
in them.
; config.el (setq org-directory "~/f/notes")
Also inside of your emacs config.el
, you need to have:
; config.el (require 'ob-clojure) (setq org-babel-clojure-backend 'cider) (require 'cider)
1.1.1 Clojurescript
Then, I add my clojurescript files. First, add the dependencies. Here you can add any dependencies you might want available to the clojurescript
repl in your org files.
; org-directory/deps.edn {:deps {org.clojure/clojure {:mvn/version "1.9.0"} org.clojure/clojurescript {:mvn/version "1.10.773"} org.clojure/test.check {:mvn/version "0.9.0"} ; this enables spec com.bhauman/figwheel-main {:mvn/version "0.2.12"} reagent {:mvn/version "1.0.0"} ;; optional but recommended com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}} :aliases {:fig {:main-opts ["-m" "figwheel.main" "-b" "dev" ;references file dev.cljs.edn "-r"]}} ; repl i guess :paths ["src"]}
Then, for figwheel, I will add the following file. I will be honest, I am not entirely sure why or how all of this is needed, but it works for me.
; org-directory/dev.cljs.edn {:main clojurescriptexamples.core}
additionally I add the file src/clojurescriptexamples/core.cljs
in the org directory to have the main file.
1.1.2 Clojure
I add the file for leiningen like so:
1.2 Running
Now, we should be able to add a code block, like so
#+BEGIN_SRC clojure :eval no-exports :exports both [1 2 3] / #+END_SRC
[1 2 3]
1 | 2 | 3 |
now, when you C-c C-c
in that block, you should be confronted with a menu. where you can choose between:
cider-jack-in-clj cider-jack-incljs ....
With this, I make the decision to start the clojure
or clojurescript
repl. I will now choose cider-jack-in-cljs
. I now have to choose between
lein clojure-cli
I will choose clojure-cli
for clojurescript. then, choose figwheel-main
to have hot reloading and more in your browser. You should also be able to choose your dev.cljs.edn
build from earlier. A repl window should also open up, as well as the browser running the compiled, hot reloaded javascript.
Note, as the cider
repl is starting, you should see:
Please reevaluate when nREPL is connected
And you will have to evaluate the block again later, like so.
[1 2 3]
1 | 2 | 3 |
If you open the console in the browser and evaluate the following block
(js/console.log "hello world")
You should see “hello world” there.
1.3 Notes
1.3.1 use :exports both
This will export your results blocks
1.3.2 use :eval no-exports
For each clojure
source block, I do not want to make the decision when I am exporting my org notes to pdf or html which repl to use. Since all of them simply define BEGIN_SRC clojure
, It would not make sense to excecute them every single time I export the page. With this in mind, I add :eval no-exports
to each block, so it ’stores’ the results for export.