Custom indentation in Clojurescript and Cider for 3rd party macro - clojure

I use the async macro in Clojurescript
(:require
[cljs.test :refer-macros [async deftest is testing run-tests]]
and Cider wants to indent it like this
(async done
(go
The Cider manual only talks about custom indentation for 1st party macros
https://cider.readthedocs.io/en/latest/indent_spec/
https://cider.readthedocs.io/en/latest/configuration/indentation/
How do I tell Ciderto use {:style/indent 1} for a 3rd party macro in Clojurescript?

This can be configured in clojure-mode (a dependency of CIDER), documentation is here.
For example, (put-clojure-indent 'async 1).

Related

Adding Front End to Existing Clojure Terminal App

I have a terminal app built in Clojure and connected to MySQL, but I would like to know the simplest way to add a front-end to it. I came across this post (that is 5 years old) that recommends ring, and set it up: Add webapp frontend to existing clojure app.
After adding deps to project, added handler function to core.clj:
(defn handler [request]
{:status 200
:headers {"Content-Type" "text/html"}
:body "Hello World"})
Started a webserver and got output "Hello World."
Ok, now what? I am familiar with templates like Figwheel that allow you to build Clojurescript right out of the box (that doesn't come with a back-end?) and tools like Reagent that allow you to write React with Clojurescript, but what I am interested in is, how to add a front-end to an already existing terminal app, in whatever framework I choose, be it plain React, Clojurescript with Reagent, Angular, or even old-fashioned HTML/CSS/Javascript. It seems there are lots of templates but no instructions for how to do it from scratch.
Any of the following would have been acceptable answers: Selmer, Hiccup, Enlive.

Clojure ^shared in namespace

I am following the pedestal tutorial, and I noticed the ^shared annotation in the code, like below :
(ns ^:shared tutorial-client.behavior
(:require [clojure.string :as string]
[io.pedestal.app.messages :as msg]))
What is it useful for ?
The ^shared annotation is for indicating to the ClojureScript compiler to compile this .clj file, where it would normally ignore it. This lets you write shared code that can be run on the client and server (as long as it doesn't use platform specific code). This was before cljx and cljc files and AFAIK is specific to the Pedestal build process, not part of vanilla ClojureScript.
The supported way to write platform specific code is using Reader Conditionals, new in Clojure 1.7.
As a side note, Pedestal App is effectively deprecated, Pedestal Server is still maintained.
It indicates that code should be compiled both as clojure, for use server-side, and as clojurescript, for use in the browser.
From the pedestal wiki:
When compilation occurs, any Clojure namespaces marked :shared will
also be compiled to ClojureScript.
(ns ^:shared tutorial-client.behavior
(:require [clojure.string :as string]
[io.pedestal.app.messages :as msg]))
For now, these files must contain the common subset of Clojure and
ClojureScript. A new feature of Clojure 1.6, feature expressions, will
allow us to break free from this restriction.

What's the right way to include a browser REPL on a page, but only in development?

I'm using Austin to set up a browser-connected REPL, and following the example of its sample project, which uses Enlive to add the REPL script to the page.
Now I'd like to deploy my app, but I don't wan't Austin or my REPL to be on the page in production. What's the intended way to use the REPL only in development?
Is there a way to use Enlive as a middleware I could use in development and not in production?
There's almost always something that uniquely distinguishes a production environment from :dev that you can use as a conditional: if in :dev, inject the result of (browser-connected-repl-js); if not, don't.
If your deployment environment doesn't have such a property, I'd suggest adding one, as this sort of "only in environment X" use case is pretty common for a lot of things.
On the other hand, if you're looking to avoid having Austin and its dependencies included in your production-targeted builds entirely without changing any of your code that uses browser-connected-repl-js, one solution might be to simply dummy up the relevant Austin namespace, e.g.:
(ns cemerick.austin.repls)
(defn browser-connected-repl-js [& _] "")
Put that in cemerick/austin/repls.clj in a directory that is included in your project.clj's non-:dev profile:source-paths. Now your code will deploy to production without Austin and its dependencies, and your code will transparently call the above dummy function (injecting nothing into your page(s)).

Prismatic Schema on Clojure 1.4?

We are evaluating Prismatic/schema for use on a project that is currently using Clojure 1.4. We would prefer not to upgrade Clojure in our project at this time. Schema requires Clojure 1.5.1, but some basic testing in the repl did not show any problems with the Clojure version changed to 1.4.
Has anyone else tried using schema on Clojure 1.4, and how has it gone?
Here's what I tried (after changing Clojure to 1.4.0 in project.clj):
(require '[schema.core :as s])
(require '[schema.macros :as sm])
(sm/defn foo ...)
(s/with-fn-validation (foo ...))
No problems. The one thing I noticed was that the schema tests completely puke (won't even run) on Clojure 1.4. This I don't really care about, but I would care if there were actual problems with project functionality.
As far as I know, Schema should work fine with 1.4. The tests were failing because they use a marker protocol (with no methods), and 1.4 doesn't like that -- but Schema itself doesn't rely on this feature. I verified that after adding a dummy method to ATestProtocol, all of the Schema tests currently pass under Clojure 1.4.0.
I don't want to promise future support for 1.4, but if you spot any issues or bugs please let us know and we'll see what we can do. As Jared pointed out above, the Google Group is probably a more appropriate place for questions like this.

Could not locate compojure in classpath

I am trying the various Getting started examples and I can get a basic hello world example working with basic HTML in the route as such
(ns hello-world
(:use compojure.core ring.adapter.jetty)
(:require [compojure.route :as route]))
(defroutes example
(GET "/" [] "<h1>Hello World Wide Web!</h1>"))
(run-jetty example {:port 8080})
But when I attempt to use the html helpers like so
(ns hello-world
(:use compojure ring.adapter.jetty)
(:require [compojure.route :as route]))
(defroutes example
(GET "/" []
(html [:h1 "Hello World"])))
(run-jetty example {:port 8080})
Then I get the following error
[null] Exception in thread "main" java.io.FileNotFoundException: Could not locate compojure__init.class or compojure.clj on classpath: (core.clj:1)
As W55tKQbuRu28Q4xv mentions in a comment, you use (:use compojure ...) in the second example. You should switch to (:use compojure.core ...) and then maybe pull in some additional dependencies for the other functionality that you use (like hiccup (<- this is a link to the GitHub repo), which is now a separate project, for the HTML-building DSL).
My guess is that you're trying to follow some tutorials written for Compojure 0.3 while using Compojure 0.4. The latter does not include the compojure namespace at all and has been slimmed down a lot, with the basic HTTP handling delegated to ring and various other pieces of functionality spun off to separate projects (like the aforementioned hiccup).
Fortunately there are good resources on the 0.3 -> 0.4 transition, e.g. this blog entry by Brenton Ashworth. If you can't find something that's been removed from Compojure proper, chances are you'll be able to learn where to find it now from that. See also this follow-up discussion on Compojure's Google group for errata and additional details.
I played around with a Compojure "Hello World" and had this problem (as well as many others that are getting muddled in my brain). Another complication is a lot of the Compojure documentation on the web is already out of date. Bottom line, these are the step you want to follow:
Have an up-to-date version of Leiningen. Make sure you follow the installation instructions on the github site. (Do not go through macports; their Leiningen is out of date.)
Follow Compojure instructions here.
Note that the file name is incorrect. It should be src/hello_www/core.clj NOT src/hello-www/core.clj.