Fork me on GitHub

clj-kondo is mad at me because of better-cond. I've updated clj-kondo to last value and deleted its .cache , any thoughts ?

Jacob O'Bryant01:04:57

no idea unfortunately 😬 I've never actually used clj-kondo. it's been on my todo list for a little while though


interesting 🙂 so the better-cond config is being generated by clj-kondo itself


clj-kondo is my partner, it's my well behaved "clojure co-pilot". I have the utmost respect and consideration for its opinions

🙂 1

While running ./task dev in a new Biff project, Calva sets up some clj-kondo configs based on dependencies it finds (I haven't yet looked into how that works). Perhaps these clj-kondo configs for better-cond and malli are generally useful in other editors?


Libraries put their clj-kondo configs in /resources/clj-kondo/clj-kondo.exports/<lib...>/config.edn so we get: and configs when the dependencies load, I guess.

Jacob O'Bryant21:04:39

:thinking_face: I just went through the clj-kondo readme a bit and installed it. if I run clj-kondo --lint src then I get 19 errors and 6 warnings, including the anti-forgery-line in your screenshot @U0516053R. Though (following the Project Setup section from the clj-kondo readme) if I run mkdir .clj-kondo; clj-kondo --lint $(clj -Spath) --dependencies --parallel --copy-configs first and then rerun clj-kondo --lint src, the errors all disappear (there are still 6 warnings, but they make sense). So maybe you just need to run that mkdir ... command? I'm guessing that's what Calva is doing automatically?

Jacob O'Bryant21:04:41

(I guess I should mention the # of warnings you get might be different since I fixed a couple just now)


the better-cond messages were not supposed to be there, because there is a configuration for better-cond already. I saw that you've stripped some better-cond cases from the code base. the sweet spot with clj-kondo is the vim integration. I use it on vim.


yesterday I was looking at this doseq, and was think that It was a better-cond one 🙂 I didnt knew clojure could handle this by itself. So can you explain what this is accomplishing and the doseq if you might . Sincerely I didnt understood..

Jacob O'Bryant03:04:34

ah yes, I think I removed a few better-cond usages last weekend (?) the doseq is looping through an XTDB transaction. (::xt/tx-ops tx) is exactly the same kind of data structure that you could pass to xtdb.api/submit-tx. so we're checking to see if there are any put operations, and if there are, we see if the documents being put-ed are chat messages. if any of them are, we render them as html and send them to all the clients

Jacob O'Bryant03:04:52

the Clojure docs page has a couple more examples of this kind of doseq usage:


out of curiosity, do you use some kind of paredit/parens navigation facility ?

Jacob O'Bryant02:04:28

Yeah, I use a couple vim plugins: vim-sexp and the excellently named vim-sexp-mappings-for-regular-people, plus a couple of my own custom mappings. and conjure for nrepl

🙂 1
Jacob O'Bryant02:04:19

I guess vim-surround also falls in the paredit category


I saw the existence of websockets in htmx. How a page would be refreshed automatically in biff ?

Jacob O'Bryant21:04:16

Usually you wouldn't refresh the whole page; instead you'd replace parts of the page. e.g this bit ( uses websockets to insert an html snippet (containing a new chat message) into the the #messages div. If you need the websocket to trigger some custom javascript/hyperscript code on the frontend (to e.g. do a page refresh), you can insert some html that runs code when it's loaded. see this (hyperscript):


I've tried the chat example . One user can see another message ? I've signed three users but they didnt saw each others messages.

Jacob O'Bryant03:04:51

hm, there might be a bug then. can each user see their own messages at least? were they all signed in at the same time? only messages from the past 10 minutes are shown, so if you signed in as three separate users on three different occasions, that might explain it.


the users can see their own message. less than 10 min delay between messages. I used 3 users two on ubuntu (one on chrome another on chrome anonymous) other on virtual machine windows acessing the ubuntu host , now with firefox

Jacob O'Bryant07:04:20

any errors in the dev console or network tab? it is odd that a user would see their own messages but not that from other users, since clients receive messages the same way regardless of if they sent them or if someone else did (i.e. when you send a message, it doesn't get inserted into the dom immediately--instead the backend renders it and sends it to you over websocket)

Jacob O'Bryant07:04:00

this is what it should look like (one window is signed in as <mailto:[email protected]|[email protected]>, the other as <mailto:[email protected]|[email protected]>)


that definitivelly didnt happen

Jacob O'Bryant07:04:55

any errors in the browser dev console or network tab?

Jacob O'Bryant07:04:19

As a first debugging step you could add these print statements to :

(defn notify-clients [{:keys [com.example/chat-clients]} tx]
+  (biff/pprint tx)
+  (biff/pprint @chat-clients)
   (doseq [[op & args] (::xt/tx-ops tx)
           :when (= op ::xt/put)
           :let [[doc] args]
@@ -51,6 +53,7 @@
                        [:div#messages {:hx-swap-oob "afterbegin"}
                         (message doc)])]
           ws @chat-clients]
+    (println "sending message")
     (jetty/send! ws html)))
then connect with two clients, send a message, and paste the output here


disregard all this. I think there might be some virtualization stuff, the windows machine navigates through proxy, It cannot establish connection, you can see past messages (from the first render, but it does not show its own new message nor other fresh ones)