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
