Clojure snippets i use

Created: Jul 14, 2020Published: Mar 28, 2023Last modified: Apr 05, 2023
Word count: 338

Snippets take a load off of boilerplate, cutting that time it takes to go from idea to first draft significantly.

Ideally these would also come with their own clj-kondo linters. Some of them do, but packaging them is a bit of a headache because it spans not just emacs, but also per-project configuration. Though I think there's fancy ways to get clj-kondo to look for linters in built jar files.

Don't forget to add these to clj, cljc, and cljs as relevant!

defn

# -*- mode: snippet -*-
# name: defn
# uuid: defn-create
# key: defn
# condition: t
# --
(defn $1
  \"$2\"
  [$3]
  $4
  )

div-for

I found myself doing this an awful lot when working on yodo. Always having a list of items, needing a :div with for and ^key magic.

Could see a variant that adds the map-indexed and [i item] bits.

# -*- mode: snippet -*-
# name: div-for
# uuid: for-with-keyed-div
# key: div-for
# condition: t
# --
(for [item $1]
  ^{:key (:id item)}
  [$2 item])

list-items

At some point i was adding this component to every view... could have kept adding all the options with defaults to the snippet to save looking it up every time I used it.

# -*- mode: snippet -*-
# name: list-items
# uuid: list-items
# key: list-items
# condition: t
# --
[lists/item-list
 {:small?  true
  :list-id :$1}
 @(rf/subscribe [::subs/linked-items item])]

re-frame

> sub

For creating a new re-frame subscription.

# -*- mode: snippet -*-
# name: sub
# uuid: sub
# key: sub
# condition: t
# --
(rf/reg-sub
  ::$1
  :<- [::subs/$2]
  (fn [items [_ $3]]
    $4))

> event

For creating a new event.

# -*- mode: snippet -*-
# name: event
# uuid: event
# key: event
# condition: t
# --
(rf/reg-event-fx
  ::$1
  [rf/trim-v]
  (fn [{:keys [db]} [$2]]
    {:db db
     :dispatch [$3]}))

> rfsub

For a quick re-sub helper.

> rfevent

For a quick re-frame dispatch helper.

# -*- mode: snippet -*-
# name: rfevent
# uuid: rfevent
# key: rfevent
# condition: t
# --
(rf/dispatch [::events/$1 $2])

It'd be fancy to get the ::events bit to source a locally used .events namespace in the current file. Same for rfsub.

> appdb

This is a useful one for quickly introspecting on your app-db. re-frame.db/app-db is your local database - this lets you walk it instantly.

# -*- mode: snippet -*-
# name: get-appdb
# key: appdb
# condition: t
# --
(get-in @re-frame.db/app-db [::db/data $1])

defcom

Defcom is currently incubating in Ralphie, but will likely be a simple clojure

library all it's own someday (once I work out the best way to break down these

features without creating a huge chain of dependencies.)

Here's a snippet I use all the time to quickly create a command. The inclusion of the namespace require is convenient if it hasn't been pulled already, but otherwise is quickly deleted after the fact.

# -*- mode: snippet -*-
# name: defcom
# uuid: defcom
# key: defcom
# condition: t
# --
(:require
   [ralph.defcom :refer [defcom]])

(defcom $1
  {:defcom/name          "$1"
   :defcom/handler
   (fn [_ _]
    $2
    )})

meta: clj for creating quick clojure source blocks in org-mode

Not a perfect use - i had to escape the snippet lines to prevent them from being handled by the .org parser.

# -*- mode: snippet -*-
# name: cljsrc
# uuid: cljsrc
# key: clj
# condition: t
# --

\#+BEGIN_SRC clojure

\#+END_SRC