Ihor Radchenko <[email protected]> writes:

> Just three more observations:
>
> 1. We can add something like
>
> (unless org-babel-clojure-backend
>   (signal 'missing-test-dependency '("Support for Clojure code
> blocks")))

I've made that change.

>
> to skip the tests when clojure is not available
>
> 2. I have clojure-cli variant installed locally and the tests
>    do not pass there. Although, it is orthogonal to the patch - look
>    like clojure-cli logic is simply not up to date (there is no -M
>    command line option in current clojure version)
>

I think that what you are saying is that the clojure-cli logic in your
Clojure installation is not up to date. The -M command line option is
available in the latest Clojure CLI
(https://clojure-doc.org/articles/tutorials/getting_started_cli/):

"clojure -M says we want to run clojure.main"

Keep in mind that I'm not a Clojure expert, so I could be
misunderstanding the problem.

> 3. If you can, please create full patches including the commit message,
>    as described in 
> https://orgmode.org/worg/org-contribute.html#commit-messages

I'll attach the patches here.

>From 7c655d983a72278d2de6662e87336b6bd65ee41f Mon Sep 17 00:00:00 2001
From: Simon Cossar <[email protected]>
Date: Wed, 20 May 2026 07:05:50 -0700
Subject: [PATCH 1/3] lisp/ob-clojure.el: Stop tangling code that is used for
 evaluation

* org-clojure.el (org-babel-expand-body:clojure,
ob-clojure--prepare-for-evaluation): Extract code that is used for
evaluation of source blocks into its own function.
(org-babel-execute:clojure): Call ob-clojure--prepare-for-evaluation
on expanded source block body.
---
 lisp/ob-clojure.el | 113 +++++++++++++++++++++++----------------------
 1 file changed, 58 insertions(+), 55 deletions(-)

diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index 8f07d3d3f..ca8083249 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -133,9 +133,8 @@
   :group 'org-babel
   :package-version '(Org . "9.7"))
 
-(defun org-babel-expand-body:clojure (body params &optional cljs-p)
-  "Expand BODY according to PARAMS, return the expanded body.
-When CLJS-P is non-nil, expand in a cljs context instead of clj."
+(defun org-babel-expand-body:clojure (body params &optional _cljs-p)
+  "Expand BODY according to PARAMS, return the expanded body."
   (let* ((vars (org-babel--get-vars params))
          (backend-override (cdr (assq :backend params)))
          (org-babel-clojure-backend
@@ -144,51 +143,30 @@ When CLJS-P is non-nil, expand in a cljs context instead of clj."
            (org-babel-clojure-backend org-babel-clojure-backend)
            (t (user-error "You need to customize `org-babel-clojure-backend'
 or set the `:backend' header argument"))))
-	 (ns (or (cdr (assq :ns params))
-		 (if (eq org-babel-clojure-backend 'cider)
-		     (or cider-buffer-ns
-			 (let ((repl-buf (cider-current-connection)))
-			   (and repl-buf (buffer-local-value
-					  'cider-buffer-ns repl-buf))))
-		   org-babel-clojure-default-ns)))
-	 (result-params (cdr (assq :result-params params)))
-	 (print-level nil)
-	 (print-length nil)
-	 (body (org-trim
-		(concat
-		 ;; Source block specified namespace :ns.
-		 (and (cdr (assq :ns params)) (format "(ns %s)\n" ns))
-		 ;; Variables binding.
-		 (if (null vars) (org-trim body)
-                   ;; Remove comments, they break (let [...] ...) bindings
-                   (let ((body (replace-regexp-in-string "^[    ]*;+.*$" "" body)))
-                     (format "(let [%s]\n%s)"
-			   (mapconcat
-			    (lambda (var)
-			      (format "%S '%S" (car var) (cdr var)))
-			    vars
-			    "\n      ")
-			   body)))))))
-    ;; If the result param is set to "output" we don't have to do
-    ;; anything special and just let the backend handle everything
-    (if (member "output" result-params)
-        body
-
-      ;; If the result is not "output" (i.e. it's "value"), disable
-      ;; stdout output and print the last returned value.  Use pprint
-      ;; instead of prn when results param is "pp" or "code".
-      (concat
-       (if (or (member "code" result-params)
-	       (member "pp" result-params))
-           (concat (if cljs-p
-                       "(require '[cljs.pprint :refer [pprint]])"
-                     "(require '[clojure.pprint :refer [pprint]])")
-                   " (pprint ")
-         "(prn ")
-       (if cljs-p
-           "(binding [cljs.core/*print-fn* (constantly nil)]"
-         "(binding [*out* (java.io.StringWriter.)]")
-       body "))"))))
+         (ns (or (cdr (assq :ns params))
+                 (if (eq org-babel-clojure-backend 'cider)
+                     (or cider-buffer-ns
+                         (let ((repl-buf (cider-current-connection)))
+                           (and repl-buf (buffer-local-value
+                                          'cider-buffer-ns repl-buf))))
+                   org-babel-clojure-default-ns)))
+         (print-level nil)
+         (print-length nil))
+    (org-trim
+     (concat
+      ;; Source block specified namespace :ns.
+      (and (cdr (assq :ns params)) (format "(ns %s)\n" ns))
+      ;; Variables binding.
+      (if (null vars) (org-trim body)
+        ;; Remove comments, they break (let [...] ...) bindings
+        (let ((body (replace-regexp-in-string "^[    ]*;+.*$" "" body)))
+          (format "(let [%s]\n%s)"
+                  (mapconcat
+                   (lambda (var)
+                     (format "%S '%S" (car var) (cdr var)))
+                   vars
+                   "\n      ")
+                  body)))))))
 
 (defvar ob-clojure-inf-clojure-filter-out)
 (defvar ob-clojure-inf-clojure-tmp-output)
@@ -300,6 +278,30 @@ The PARAMS from Babel are not used in this function."
      (format "%s %s" cmd (org-babel-process-file-name script-file))
      "")))
 
+(defun ob-clojure--prepare-for-evaluation (expanded-body params cljs-p)
+  "Wrap EXPANDED-BODY in a print expression, depending on PARAMS and CLJS-P."
+  (let* ((result-params (cdr (assq :result-params params)))
+         ;; If the result param is set to "output", we don't have to do
+         ;; anything special and just let the backend handle everything.
+         (output (if (member "output" result-params)
+                     expanded-body
+                   ;; If the result param is not "output" (i.e. it's set to "value"),
+                   ;; disable stdout output and print the last returned value.
+                   ;; Use pprint instead of prn when result param is "pp" or "code".
+                   (concat
+                    (if (or (member "code" result-params)
+                            (member "pp" result-params))
+                        (concat (if cljs-p
+                                    "(require '[cljs.pprint :refer [pprint]])"
+                                  "(require '[clojure.pprint :refer [pprint]])")
+                                " (pprint")
+                      "(prn ")
+                    (if cljs-p
+                        "(binding [cljs.core/*print-fn* (constantly nil)])"
+                      "(binding [*out* (java.io.StringWriter.)]")
+                    expanded-body "))"))))
+    output))
+
 (defun org-babel-execute:clojure (body params &optional cljs-p)
   "Execute the BODY block of Clojure code with PARAMS using Babel.
 When CLJS-P is non-nil, execute with a ClojureScript backend
@@ -321,23 +323,24 @@ or set the `:backend' header argument"
          ;; ClojureScript syntax when we either evaluate a
          ;; ClojureScript source block or use the nbb backend.
          (cljs-p (or cljs-p (eq org-babel-clojure-backend 'nbb))))
-    (let* ((expanded (org-babel-expand-body:clojure body params cljs-p))
+    (let* ((expanded (org-babel-expand-body:clojure body params))
+           (prepared (ob-clojure--prepare-for-evaluation expanded params cljs-p))
 	   (result-params (cdr (assq :result-params params)))
 	   result)
       (setq result
 	    (cond
 	     ((eq org-babel-clojure-backend 'inf-clojure)
-	      (ob-clojure-eval-with-inf-clojure expanded params))
+	      (ob-clojure-eval-with-inf-clojure prepared params))
              ((eq org-babel-clojure-backend 'clojure-cli)
-              (ob-clojure-eval-with-cmd ob-clojure-cli-command expanded))
+              (ob-clojure-eval-with-cmd ob-clojure-cli-command prepared))
              ((eq org-babel-clojure-backend 'babashka)
-	      (ob-clojure-eval-with-cmd ob-clojure-babashka-command expanded))
+	      (ob-clojure-eval-with-cmd ob-clojure-babashka-command prepared))
              ((eq org-babel-clojure-backend 'nbb)
-	      (ob-clojure-eval-with-cmd ob-clojure-nbb-command expanded))
+	      (ob-clojure-eval-with-cmd ob-clojure-nbb-command prepared))
 	     ((eq org-babel-clojure-backend 'cider)
-	      (ob-clojure-eval-with-cider expanded params cljs-p))
+	      (ob-clojure-eval-with-cider prepared params cljs-p))
 	     ((eq org-babel-clojure-backend 'slime)
-	      (ob-clojure-eval-with-slime expanded params))
+	      (ob-clojure-eval-with-slime prepared params))
              (t (user-error "Invalid backend"))))
       (org-babel-result-cond result-params
         result
-- 
2.54.0

>From 2acde412845f7a4b276bf391b7c041ffa4a7620d Mon Sep 17 00:00:00 2001
From: Simon Cossar <[email protected]>
Date: Wed, 20 May 2026 07:57:09 -0700
Subject: [PATCH 2/3] testing/lisp/test-ob-clojure.el: Add tests

* test-ob-clojure.el (ob-clojure/org-babel-tangle): Test that when a
source block's :results parameter is set to "value", the tangled code
does not include `prn' statements.
(ob-clojure/org-babel-execute): Test that :result-params "value" and
"output" values are correctly handled.
---
 testing/lisp/test-ob-clojure.el | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/testing/lisp/test-ob-clojure.el b/testing/lisp/test-ob-clojure.el
index 4784f33c6..e4e02f783 100644
--- a/testing/lisp/test-ob-clojure.el
+++ b/testing/lisp/test-ob-clojure.el
@@ -23,13 +23,37 @@
 ;; Org tests for ob-clojure.el live here
 
 ;;; Code:
-
 (require 'org-test "../testing/org-test")
 
 (unless (featurep 'ob-clojure)
   (signal 'missing-test-dependency '("Support for Clojure code blocks")))
 
-;; FIXME: The old tests where totally off.  We need to write new tests.
+;; tangle
+(ert-deftest ob-clojure/org-babel-tangle ()
+  "org-babel-tangle returns the exact body of the source block."
+  (org-test-with-temp-text-in-file
+   "#+begin_src clojure :tangle \"tangle.clj\" :results value\n
+(+ 1 2)\n#+end_src"
+   (unwind-protect
+       (progn (org-babel-tangle)
+              (with-temp-buffer
+                (insert-file-contents "tangle.clj")
+                (let ((tangled (buffer-string)))
+                  (should
+                   (string-match-p "^(\\+ 1 2)\\\n$" tangled)))))
+     (delete-file "tangle.clj"))))
+
+;; execute
+(ert-deftest ob-clojure/org-babel-execute ()
+  "org-babel-execute:clojure correctly handles :result-params."
+  (should (equal 3
+                 (org-babel-execute:clojure
+                  "(+ 1 2)"
+                  '((:result-params "value")))))
+  (should (equal ""
+                 (org-babel-execute:clojure
+                  "(+ 1 2)"
+                  '((:result-params "output"))))))
 
 (provide 'test-ob-clojure)
 
-- 
2.54.0

>From 6855cb78c568e24d6354a0d1d107f2013239b3ba Mon Sep 17 00:00:00 2001
From: Simon Cossar <[email protected]>
Date: Mon, 6 Jul 2026 11:46:51 -0700
Subject: [PATCH 3/3] testing/lisp/test-ob-clojure.el: Simplify check for
 Clojure support.

* test-ob-clojure.el: Simplify the conditional that's used to check
for Clojure support.
---
 testing/lisp/test-ob-clojure.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/testing/lisp/test-ob-clojure.el b/testing/lisp/test-ob-clojure.el
index e4e02f783..a6f6a5017 100644
--- a/testing/lisp/test-ob-clojure.el
+++ b/testing/lisp/test-ob-clojure.el
@@ -25,7 +25,7 @@
 ;;; Code:
 (require 'org-test "../testing/org-test")
 
-(unless (featurep 'ob-clojure)
+(unless org-babel-clojure-backend
   (signal 'missing-test-dependency '("Support for Clojure code blocks")))
 
 ;; tangle
-- 
2.54.0

--
Simon Cossar

Reply via email to