UXBOX source code browsing with Emacs+Cider

The Clojure and ClojureScript application, which is impressive in its functionality and beautifully structured source code – UXBOX (by uxbox.io).

Using Emacs+Cider for UXBOX source code browsing under Linux. To set up Emacs for Clojure and ClojureScript with Cider, see e.g.: My Emacs configuration.

Clone the UXBOX source code

In a subdirectory of your own choosing execute the following:

1git clone https://github.com/uxbox/uxbox.git

Which clones the UXBOX source code into a newly created uxbox subdirectory.

Edit some UXBOX container files

We want to run emacs from inside the UXBOX Docker container (beware of possible security implications –check your firewall) and have its GUI displayed on the host's screen. To accomplish this some files need to be changed, as follows:

manage.sh

Change the Docker run statement in manage.sh to the following:

1docker run --net=host -ti \
2         -v `pwd`:/home/uxbox/uxbox  \
3         -v $HOME/.m2:/home/uxbox/.m2 \
4         -v $HOME/.gitconfig:/home/uxbox/.gitconfig \
5         -v $HOME/.lein:/home/uxbox/.lein \
6         -p 3449:3449 -p 6060:6060 -p 9090:9090 $IMGNAME:$REV

Which uses --net=host to use the host's network stack inside the container. Also maps (additionally) the ~/.lein subdirectory. (The -p 3449:3449 -p 6060:6060 -p 9090:9090 are now superfluous but I've left them in.)

docker/Dockerfile

Change docker/Dockerfile to include Emacs stuff (unzip to view inside jars and the silver searcher):

1RUN apt-get update -yq &&  \
2    apt-get install -yq bash git tmux vim openjdk-8-jdk rlwrap build-essential \
3                        postgresql-9.6 postgresql-contrib-9.6 imagemagick webp \
4                        sudo python unzip silversearcher-ag emacs

(The python package is included to prevent a gulp related error –it needs python somewhere.)

docker/files/start.sh

Change docker/files/start.sh to comment out the figwheel line (we'll start it from Emacs):

1tmux new-window -t uxbox:1 -n 'figwheel'
2tmux select-window -t uxbox:1
3tmux send-keys -t uxbox 'cd uxbox/frontend' enter C-l
4#tmux send-keys -t uxbox 'npm run figwheel' enter

frontend/scripts/figwheel.clj

Change options so that the local backend is used.

1(def options
2  {;"uxbox.config.url" "https://demo.uxbox.io/api"
3   "uxbox.config.url" "http://127.0.0.1:6060/api"
4   })

Note the single semicolon ; (a double semicolon ;; results in an error during figwheel execution).

frontend/project.clj

Change under Build to add piggieback.

1;; Build
2[com.cemerick/piggieback "0.2.2"]
3[figwheel-sidecar "0.5.9" :scope "provided"]
4[environ "1.1.0"]

And add nrepl options at the end, right above :clean-targets:

1:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
2:clean-targets ^{:protect false} ["resources/public/js" "target"]

Build and run the Docker container

1./manage.sh build

If all went well with the build.

1./manage.sh run

This will take some time to initialize.

In the backend tmux tab (Ctrl-b 2)

Start a headless REPL for the backend source code.

1lein trampoline repl :headless

Jot down the port on which the nREPL server started.

Create a new tmux tab (Ctrl-b c) to configure and run Emacs

Use Ctrl-b c to create a new tmux tab.

Set up your Emacs configuration with Cider.

I'm using my own config, as follows:

1git clone https://github.com/maridonkers/emacs-config.git /home/uxbox/.emacs.d

Setting up Emacs for source code browsing

First enable access for X-Windows (outside the Docker container):

1xhost +LOCAL:

Set the DISPLAY variable, start the Emacs daemon and edit the backend/project.clj and frontend/project.clj files in the uxbox subdirectory.

1export DISPLAY=:0
2emacs --daemon
3cd uxbox
4emacsclient -nc backend/project.clj frontend/project.clj

(If emacs --daemon or emacsclient fails then re-run emacs --daemon and try again.)

Connect to backend REPL and start the backend

In your Emacs GUI switch to the backend/project.clj buffer and use M-x cider-connect to connect to the backend REPL. Normally you can use the default (localhost) and also press ENTER for the port number (which automatically finds the port number). If it doesn't work then use the jotted down backend REPL port number.

The backend REPL should now show up in a separate Emacs buffer. Now start the backend by typing (start) in the backend REPL buffer:

1(start)

In the frontend tmux tab (Ctrl-b 1)

Start a headless REPL for the frontend source code.

1lein trampoline repl :headless

Jot down the port on which the nREPL server started.

Connect to frontend REPL and start the frontend

In Emacs switch to the frontend/project.clj buffer and use M-x cider-connect to connect to the frontend REPL. Normally you can use the default (localhost) and also press ENTER for the port number (which automatically finds the port number). If it doesn't work then use the jotted down frontend REPL port number.

The frontend REPL should now show up in a separate Emacs buffer. Now start the frontend by starting figwheel in the frontend REPL buffer:

1(load-file "scripts/figwheel.clj")

Load or reload the page

The frontend REPL reports Prompt will show when Figwheel connects to your application, which occurs when the page with the ClojureScript code is loaded or reloaded. So (re)load the http://localhost:3449 page.

Now the Figwheel prompt is shown.

Browse the UXBOX source code

Now you're ready to browse through the UXBOX source code, using Emacs+Cider features (such as cider-doc to get documentation and cider-find-var to jump to a symbol).

(If Emacs+Cider features don't work right away then just throw in an Ctrl+c+k cider-load-buffer to kick it.)

Manage repl connections

Sometimes you require a specific repl to be the active connection for a source file. E.g. for .cljc files. There is a section in the CIDER documentation on this: Managing Connections.

Posts in this Series