Hi Nicolas,

The new Org-mode release 9.0 made me realize that I never finished some of my work with Org-babel-clojure.

I noticed that you included some of my previous fixes in Org-babel-clojure, so here are the latest work I did. I updated it to work with the latest code on Git. I did two things with these fixes:


(1) I better handle any possible error or exceptions that may be raised by nREPL by displaying any errors in the RESULTS section

(2) I added a new header option called ":show-process" which create a new window/buffer to display anything that is outputted by the Clojure code in the code block.


In the past, I did refer to this as ":async", but as we discussed at that time, it really was not async. So I changed the naming of this new feature to remove this ambiguity.

One thing I noticed in this process is that you actually did update worg with the documentation of ":async" but didn't add the actual Org-babel-clojure code modifications.

In any case, I did update the worg documentation accordingly too.

Finally I updated ORG-NEWS in the 9.1 section.

See the patch files attached to this email.


Thanks!


Take care,


Fred

From df8284b45c35e0c1dcbccf40ba7b76fd18270b90 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <f...@fgiasson.com>
Date: Mon, 7 Nov 2016 13:48:50 -0500
Subject: [PATCH 1/2] Better error handling with nREPL. Displaying any possible
 errors or exceptions in the result block. Adding a new :show-process header
 option such that the underlying process of a Clojure block code get output in
 a new buffer and a new window such that the developer can see what is going
 on.

---
 lisp/ob-clojure.el | 106 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 82 insertions(+), 24 deletions(-)

diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index 72ea77d..4800c9a 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
 
-;; Author: Joel Boehland, Eric Schulte, Oleh Krehel
+;; Author: Joel Boehland, Eric Schulte, Oleh Krehel, Frederick Giasson
 ;;
 ;; Keywords: literate programming, reproducible research
 ;; Homepage: http://orgmode.org
@@ -84,34 +84,92 @@
       body)))
 
 (defun org-babel-execute:clojure (body params)
-  "Execute a block of Clojure code with Babel."
+  "Execute a block of Clojure code with Babel. The underlying process 
performed by the
+  code block can be output using the :show-process parameter"
   (let ((expanded (org-babel-expand-body:clojure body params))
-       result)
+        (sbuffer "*Clojure Show Process Sub Buffer*")
+        (show (if (assoc :show-process params) t nil))
+        (response (cons 'dict nil))
+        status
+        result)
     (cl-case org-babel-clojure-backend
       (cider
        (require 'cider)
        (let ((result-params (cdr (assq :result-params params))))
-        (setq result
-              (nrepl-dict-get
-               (nrepl-sync-request:eval
-                expanded (cider-current-connection) (cider-current-session))
-               (if (or (member "output" result-params)
-                       (member "pp" result-params))
-                   "out"
-                 "value")))))
-      (slime
-       (require 'slime)
-       (with-temp-buffer
-        (insert expanded)
-        (setq result
-              (slime-eval
-               `(swank:eval-and-grab-output
-                 ,(buffer-substring-no-properties (point-min) (point-max)))
-               (cdr (assq :package params)))))))
-    (org-babel-result-cond (cdr (assq :result-params params))
-      result
-      (condition-case nil (org-babel-script-escape result)
-       (error result)))))
+         ; Check if the user want show the process in an output buffer/window
+         (when show
+           ; Create a new window with the show output buffer
+           (switch-to-buffer-other-window sbuffer)
+
+           ; Run the Clojure code in nREPL
+           (nrepl-request:eval
+            expanded 
+            (lambda (resp) 
+              (when (member "out" resp)
+                ; Print the output of the nREPL in the output buffer
+                (princ (nrepl-dict-get resp "out") (get-buffer sbuffer)))
+              (when (member "ex" resp)
+                ; In case there is an exception, then add it to the output 
buffer as well
+                (princ (nrepl-dict-get resp "ex") (get-buffer sbuffer))
+                (princ (nrepl-dict-get resp "root-ex") (get-buffer sbuffer)))
+              (when (member "err" resp)
+                ; In case there is an error, then add it to the output buffer 
as well
+                (princ (nrepl-dict-get resp "err") (get-buffer sbuffer)))
+              (nrepl--merge response resp)
+              ; Update the status of the nREPL output session
+              (setq status (nrepl-dict-get response "status")))
+            (cider-current-connection) 
+            (cider-current-session))
+           
+           ; Wait until the nREPL code finished to be processed
+           (while (not (member "done" status))
+             (nrepl-dict-put response "status" (remove "need-input" status))
+             (accept-process-output nil 0.01)
+             (redisplay))
+
+           ; Delete the show buffer & window when the processing is finalized
+           (let ((wins (get-buffer-window-list sbuffer nil t)))
+             (dolist (win wins)
+               (delete-window win))
+             (kill-buffer sbuffer))
+
+           ; Put the output or the value in the result section of the code 
block
+           (setq result (concat (nrepl-dict-get response 
+                                                (if (or (member "output" 
result-params)
+                                                        (member "pp" 
result-params))
+                                                    "out"
+                                                  "value"))
+                                (nrepl-dict-get response "ex")
+                                (nrepl-dict-get response "root-ex")
+                                (nrepl-dict-get response "err"))))
+         ; Check if user want to run code without showing the process
+         (when (not show)
+           (setq response (let ((nrepl-sync-request-timeout 
+                                 org-babel-clojure-sync-nrepl-timeout))
+                            (nrepl-sync-request:eval
+                             expanded (cider-current-connection) 
(cider-current-session))))
+           (setq result
+                 (concat 
+                  (nrepl-dict-get response (if (or (member "output" 
result-params)
+                                                   (member "pp" result-params))
+                                               "out"
+                                             "value"))
+                  (nrepl-dict-get response "ex")
+                  (nrepl-dict-get response "root-ex")
+                  (nrepl-dict-get response "err"))))))
+       (slime
+        (require 'slime)
+        (with-temp-buffer
+          (insert expanded)
+          (setq result
+                (slime-eval
+                 `(swank:eval-and-grab-output
+                   ,(buffer-substring-no-properties (point-min) (point-max)))
+                 (cdr (assq :package params)))))))
+      (org-babel-result-cond (cdr (assq :result-params params))
+        result
+        (condition-case nil (org-babel-script-escape result)
+          (error result)))))
 
 (provide 'ob-clojure)
 
-- 
1.9.5.msysgit.0

From 89c8ff0e8784d1ccafc1a6fa5ede8d22bbb667b8 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <f...@fgiasson.com>
Date: Mon, 7 Nov 2016 14:09:30 -0500
Subject: [PATCH] Adding documentation for the new :show-process header option
 for Org-babel-clojure

---
 org-contrib/babel/languages/ob-doc-clojure.org | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/org-contrib/babel/languages/ob-doc-clojure.org 
b/org-contrib/babel/languages/ob-doc-clojure.org
index 9f1b8b1..670e7aa 100644
--- a/org-contrib/babel/languages/ob-doc-clojure.org
+++ b/org-contrib/babel/languages/ob-doc-clojure.org
@@ -145,26 +145,29 @@ Another source for information on options is this page at 
Worg:
  
 Next, a similar process for executing code will be used with Clojure.
 
-* Using Asynchronous Evaluations
-Org-babel-clojure does support asynchronous evaluation of the code blocks. To
-evaluate some code asynchronously, you only have to specify the =:async= option
+* Show Process Of Code Block Execution
+You can tell Org-babel-clojure to output the process of a running code block.
+
+To show that output you only have to specify the =:show-process= option
 in the code block's header like this:
 
 #+begin_example
-#+BEGIN_SRC clojure :results output :async
+#+BEGIN_SRC clojure :results output :show-process
   (dotimes [n 10]
     (println n ".")
     (Thread/sleep 500))
 #+END_SRC
 #+end_example
 
-If =:async= is specified that way, then when you will run the code using
-=C-c C-c= then a new window will open in Emacs. Everything that is output
+If =:show-process= is specified that way, then when you will run the code using
+=C-c C-c= a new window will open in Emacs. Everything that is output
 by the REPL will immediately be added to that new window.
 
 When the processing of the code is finished, then the window and its
 buffer will be closed and the results will be reported in the
-=#+RESULTS= section. Note that the =:results= parameter like normally. If
+=#+RESULTS= section. 
+
+Note that the =:results= parameter's behavior is *not* changed. If
 =silent= is specified, then no result will be displayed. If =output= is
 specified then all the output from the window will appears in the results
 section. If =value= is specified, then only the last returned value of
-- 
1.9.5.msysgit.0

From c49616a7cccc51c3d3b5f3fda0db2594834b86f6 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <f...@fgiasson.com>
Date: Mon, 7 Nov 2016 14:08:03 -0500
Subject: [PATCH 2/2] Update ORG-NEWS to mention the new :show-process feature
 for Org-babel-clojure

---
 etc/ORG-NEWS | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index a360e35..95c97a7 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -27,6 +27,38 @@ into
 ** New features
 
 *** Horizontal rules are no longer ignored in LaTeX table math mode
+*** Org-babel-clojure :show-process
+
+A new block code header has been created for Org-babel-clojure that enables
+developers to output the process of an ongoing process into a new 
window/buffer.
+
+You can tell Org-babel-clojure to output the process of a running code block.
+
+To show that output you only have to specify the =:show-process= option
+in the code block's header like this:
+
+#+begin_example
+#+BEGIN_SRC clojure :results output :show-process
+  (dotimes [n 10]
+    (println n ".")
+    (Thread/sleep 500))
+#+END_SRC
+#+end_example
+
+If =:show-process= is specified that way, then when you will run the code using
+=C-c C-c= a new window will open in Emacs. Everything that is output
+by the REPL will immediately be added to that new window.
+
+When the processing of the code is finished, then the window and its
+buffer will be closed and the results will be reported in the
+=#+RESULTS= section. 
+
+Note that the =:results= parameter's behavior is *not* changed. If
+=silent= is specified, then no result will be displayed. If =output= is
+specified then all the output from the window will appears in the results
+section. If =value= is specified, then only the last returned value of
+the code will be displayed in the results section.
+
 
 * Version 9.0
 
-- 
1.9.5.msysgit.0

Reply via email to