From 7a93225218f689d5f4de382f16c536f92307f9c4 Mon Sep 17 00:00:00 2001
From: Vedang Manerikar <ved.manerikar@gmail.com>
Date: Mon, 2 Dec 2024 08:06:17 +0530
Subject: [PATCH] Add configuration for Clojure programming

---
 unravel-emacs.org                | 55 +++++++++++++++++++++++++++++++-
 unravel-modules/unravel-langs.el | 47 +++++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/unravel-emacs.org b/unravel-emacs.org
index e437720..a620a8b 100644
--- a/unravel-emacs.org
+++ b/unravel-emacs.org
@@ -1,4 +1,4 @@
-#+title: GNU Emacs configuration
+#+title: GNU Emacs configuration for Emacs 29 and above
 #+author: Vedang Manerikar
 #+email: vedang@unravel.tech
 #+language: en
@@ -5151,6 +5151,59 @@ To install ~zig~ and ~zls~ on MacOS:
     :hook ((zig-mode . eglot-ensure)))
 #+end_src
 
+** The =unravel-langs.el= section for Clojure
+
+Clojure is my favorite programming language, and it has been my bread and butter language for well over a decade. I can only hope and pray for this to continue.
+
+#+begin_src emacs-lisp :tangle "unravel-modules/unravel-langs.el"
+  ;;; Configuration for Clojure programming
+  (use-package clojure-mode
+    :ensure t)
+
+  (use-package cider
+    :ensure t
+    :after clojure-mode
+    :config
+    (defun cider-repl-prompt-on-newline (ns)
+      "Return a prompt string with newline.
+  NS is the namespace information passed into the function by cider."
+      (concat ns ">\n"))
+    (setq cider-repl-prompt-function #'cider-repl-prompt-on-newline))
+
+  (use-package clj-refactor
+    :ensure t
+    :after clojure-mode
+    :hook
+    ((clojure-mode . clj-refactor-mode))
+    :config
+    (cljr-add-keybindings-with-prefix "C-c m")
+    ;; Don't magically add stuff to the namespace requires form (because
+    ;; for big projects this operation is slow) it's easier to do this
+    ;; by hand (=add-missing= operation) after you've typed out what you
+    ;; wanted to.
+    (setq cljr-magic-requires nil))
+
+  (use-package clojure-snippets
+    :ensure t
+    :after clojure-mode)
+
+  (use-package jet
+    :ensure t
+    :config
+    (defun json->edn ()
+    "Convert the selected region, or entire file, from JSON to EDN."
+    (interactive)
+    (let ((b (if mark-active (region-beginning) (point-min)))
+          (e (if mark-active (region-end) (point-max)))
+          (jet (when (executable-find "jet")
+                 "jet --pretty --keywordize keyword --from json --to edn")))
+      (if jet
+          (let ((p (point)))
+            (shell-command-on-region b e jet (current-buffer) t)
+            (goto-char p))
+        (user-error "Could not find jet installed")))))
+#+end_src
+
 ** Finally, we provide the =unravel-langs.el= module
 :PROPERTIES:
 :CUSTOM_ID: h:924224F1-61A0-4CCD-A3C3-4F230D3CF0A0
diff --git a/unravel-modules/unravel-langs.el b/unravel-modules/unravel-langs.el
index 4365078..b14957a 100644
--- a/unravel-modules/unravel-langs.el
+++ b/unravel-modules/unravel-langs.el
@@ -402,4 +402,51 @@ modifications."
 ;;; recommend it, but that's just me.
   :hook ((zig-mode . eglot-ensure)))
 
+;;; Configuration for Clojure programming
+(use-package clojure-mode
+  :ensure t)
+
+(use-package cider
+  :ensure t
+  :after clojure-mode
+  :config
+  (defun cider-repl-prompt-on-newline (ns)
+    "Return a prompt string with newline.
+NS is the namespace information passed into the function by cider."
+    (concat ns ">\n"))
+  (setq cider-repl-prompt-function #'cider-repl-prompt-on-newline))
+
+(use-package clj-refactor
+  :ensure t
+  :after clojure-mode
+  :hook
+  ((clojure-mode . clj-refactor-mode))
+  :config
+  (cljr-add-keybindings-with-prefix "C-c m")
+  ;; Don't magically add stuff to the namespace requires form (because
+  ;; for big projects this operation is slow) it's easier to do this
+  ;; by hand (=add-missing= operation) after you've typed out what you
+  ;; wanted to.
+  (setq cljr-magic-requires nil))
+
+(use-package clojure-snippets
+  :ensure t
+  :after clojure-mode)
+
+(use-package jet
+  :ensure t
+  :config
+  (defun json->edn ()
+  "Convert the selected region, or entire file, from JSON to EDN."
+  (interactive)
+  (let ((b (if mark-active (region-beginning) (point-min)))
+        (e (if mark-active (region-end) (point-max)))
+        (jet (when (executable-find "jet")
+               "jet --pretty --keywordize keyword --from json --to edn")))
+    (if jet
+        (let ((p (point)))
+          (shell-command-on-region b e jet (current-buffer) t)
+          (goto-char p))
+      (user-error "Could not find jet installed")))))
+
 (provide 'unravel-langs)