updated my code. I followed your suggestions. But modify code one by one messed code up. So I merge all related commits into one commit. Sorry for this.

>From 23ef274fd418c876be85871f8da34738ae15ffd5 Mon Sep 17 00:00:00 2001
From: stardiviner <numbch...@gmail.com>
Date: Thu, 8 Mar 2018 17:15:58 +0800
Subject: [PATCH] * ob-js.el: support :session for many JS packages.

- ob-js.el: support :session for js-comint.
- ob-js.el: support :session for Indium Node.js REPL.
- ob-js.el: (org-babel-js-initiate-session): merge the `unless' into the `cond'
---
 etc/ORG-NEWS  |   8 ++++
 lisp/ob-js.el | 141 ++++++++++++++++++++++++++++++++++++----------------------
 2 files changed, 97 insertions(+), 52 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 10687ba83..5cbc10b8b 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -107,6 +107,14 @@ document, use =shrink= value instead, or in addition to align:
 #+END_EXAMPLE
 
 ** New features
+*** Add support for ob-js :session with Indium
+You can specify :session for js src block with ~*JS REPL*~.
+*** Add support for ob-js :session with js-comint
+After you launched js-comint REPL. You can specify :session for js
+src block with ~*Javascript REPL*~.
+*** Add support for ob-js :session with skewer-mode
+After you launched skewer-mode REPL. You can specify :session for js
+src block with ~*skewer-repl*~.
 *** Add support for open src block in below window
 Set option ~org-src-window-setup~ to ~'split-window-below~.
 *** Add support for links to LaTeX equations in HTML export
diff --git a/lisp/ob-js.el b/lisp/ob-js.el
index 38c8c39ac..93c08c162 100644
--- a/lisp/ob-js.el
+++ b/lisp/ob-js.el
@@ -41,6 +41,9 @@
 (require 'ob)
 
 (declare-function run-mozilla "ext:moz" (arg))
+(declare-function run-js "js-comint" (cmd))
+(declare-function indium-run-node "indium-nodejs" (command))
+(declare-function indium-eval "indium-interaction" (string &optional callback))
 
 (defvar org-babel-default-header-args:js '()
   "Default header arguments for js code blocks.")
@@ -52,7 +55,11 @@
   "Name of command used to evaluate js blocks."
   :group 'org-babel
   :version "24.1"
-  :type 'string)
+  :type '(choice (const "node")
+		             (const "mozrepl")
+		             (const "js-comint")
+		             (const "skewer-mode"))
+  :safe #'stringp)
 
 (defvar org-babel-js-function-wrapper
   "require('sys').print(require('sys').inspect(function(){\n%s\n}()));"
@@ -62,32 +69,40 @@
   "Execute a block of Javascript code with org-babel.
 This function is called by `org-babel-execute-src-block'"
   (let* ((org-babel-js-cmd (or (cdr (assq :cmd params)) org-babel-js-cmd))
+	       (session (cdr (assq :session params)))
          (result-type (cdr (assq :result-type params)))
          (full-body (org-babel-expand-body:generic
-		     body params (org-babel-variable-assignments:js params)))
-	 (result (if (not (string= (cdr (assq :session params)) "none"))
-		     ;; session evaluation
-		     (let ((session (org-babel-prep-session:js
-				     (cdr (assq :session params)) params)))
-		       (nth 1
-			    (org-babel-comint-with-output
-				(session (format "%S" org-babel-js-eoe) t body)
-			      (mapc
-			       (lambda (line)
-				 (insert (org-babel-chomp line))
-				 (comint-send-input nil t))
-			       (list body (format "%S" org-babel-js-eoe))))))
-		   ;; external evaluation
-		   (let ((script-file (org-babel-temp-file "js-script-")))
-		     (with-temp-file script-file
-		       (insert
-			;; return the value or the output
-			(if (string= result-type "value")
-			    (format org-babel-js-function-wrapper full-body)
-			  full-body)))
-		     (org-babel-eval
-		      (format "%s %s" org-babel-js-cmd
-			      (org-babel-process-file-name script-file)) "")))))
+		                 body params (org-babel-variable-assignments:js params)))
+	       (result (if (not (string= (cdr (assq :session params)) "none"))
+		                 ;; session evaluation
+		                 (cond
+		                  ;; Indium Node
+		                  ((string= "*JS REPL*" session)
+		                   (require 'indium-repl)
+		                   (unless (get-buffer session)
+			                   (indium-run-node))
+		                   (indium-eval full-body))
+		                  (t
+		                   (let ((session (org-babel-prep-session:js
+				                               (cdr (assq :session params)) params)))
+			                   (nth 1
+			                        (org-babel-comint-with-output
+				                          (session (format "%S" org-babel-js-eoe) t body)
+				                        (dolist ((code (list body (format "%S" org-babel-js-eoe))))
+				                          (lambda (code)
+				                            (insert (org-babel-chomp code))
+				                            (comint-send-input nil t))))))))
+		               ;; external evaluation
+		               (let ((script-file (org-babel-temp-file "js-script-")))
+		                 (with-temp-file script-file
+		                   (insert
+			                  ;; return the value or the output
+			                  (if (string= result-type "value")
+			                      (format org-babel-js-function-wrapper full-body)
+			                    full-body)))
+		                 (org-babel-eval
+		                  (format "%s %s" org-babel-js-cmd
+			                        (org-babel-process-file-name script-file)) "")))))
     (org-babel-result-cond (cdr (assq :result-params params))
       result (org-babel-js-read result))))
 
@@ -97,16 +112,16 @@ If RESULTS look like a table, then convert them into an
 Emacs-lisp table, otherwise return the results as a string."
   (org-babel-read
    (if (and (stringp results)
-	    (string-prefix-p "[" results)
-	    (string-suffix-p "]" results))
+	          (string-prefix-p "[" results)
+	          (string-suffix-p "]" results))
        (org-babel-read
         (concat "'"
                 (replace-regexp-in-string
                  "\\[" "(" (replace-regexp-in-string
                             "\\]" ")" (replace-regexp-in-string
                                        ",[[:space:]]" " "
-				       (replace-regexp-in-string
-					"'" "\"" results))))))
+				                               (replace-regexp-in-string
+					                              "'" "\"" results))))))
      results)))
 
 (defun org-babel-js-var-to-js (var)
@@ -120,42 +135,64 @@ specifying a variable of the same value."
 (defun org-babel-prep-session:js (session params)
   "Prepare SESSION according to the header arguments specified in PARAMS."
   (let* ((session (org-babel-js-initiate-session session))
-	 (var-lines (org-babel-variable-assignments:js params)))
+	       (var-lines (org-babel-variable-assignments:js params)))
     (when session
       (org-babel-comint-in-buffer session
-	(sit-for .5) (goto-char (point-max))
-	(mapc (lambda (var)
-		(insert var) (comint-send-input nil t)
-		(org-babel-comint-wait-for-output session)
-		(sit-for .1) (goto-char (point-max))) var-lines)))
+	      (sit-for .5) (goto-char (point-max))
+	      (mapc (lambda (var)
+		            (insert var) (comint-send-input nil t)
+		            (org-babel-comint-wait-for-output session)
+		            (sit-for .1) (goto-char (point-max))) var-lines)))
     session))
 
 (defun org-babel-variable-assignments:js (params)
   "Return list of Javascript statements assigning the block's variables."
   (mapcar
    (lambda (pair) (format "var %s=%s;"
-			  (car pair) (org-babel-js-var-to-js (cdr pair))))
+			                (car pair) (org-babel-js-var-to-js (cdr pair))))
    (org-babel--get-vars params)))
 
 (defun org-babel-js-initiate-session (&optional session)
   "If there is not a current inferior-process-buffer in SESSION
 then create.  Return the initialized session."
-  (unless (string= session "none")
-    (cond
-     ((string= "mozrepl" org-babel-js-cmd)
-      (require 'moz)
-      (let ((session-buffer (save-window-excursion
-			      (run-mozilla nil)
-			      (rename-buffer session)
-			      (current-buffer))))
-	(if (org-babel-comint-buffer-livep session-buffer)
-	    (progn (sit-for .25) session-buffer)
-	  (sit-for .5)
-	  (org-babel-js-initiate-session session))))
-     ((string= "node" org-babel-js-cmd )
-      (error "Session evaluation with node.js is not supported"))
-     (t
-      (error "Sessions are only supported with mozrepl add \":cmd mozrepl\"")))))
+  (cond
+   ((string= session "none")
+    (error "Session evaluation is not supported"))
+   ((string= "*Javascript REPL*" session)
+    (require 'js-comint)
+    (let ((session-buffer "*Javascript REPL*"))
+      (if (and (org-babel-comint-buffer-livep (get-buffer session-buffer))
+	             (comint-check-proc session-buffer))
+	        session-buffer
+	      (call-interactively 'run-js)
+	      (sit-for .5)
+	      session-buffer)))
+   ((string= "*skewer-repl*" session) ; `skewer-mode'
+    (require 'skewer-repl)
+    (let ((session-buffer (get-buffer "*skewer-repl*")))
+      (if (and (org-babel-comint-buffer-livep (get-buffer session-buffer))
+	             (comint-check-proc session-buffer))
+	        session-buffer
+	      ;; start skewer REPL.
+	      (sit-for .5)
+	      (httpd-start)
+	      (run-skewer)
+	      (sit-for .5)
+	      session-buffer)))
+   ((string= "mozrepl" org-babel-js-cmd)
+    (require 'moz)
+    (let ((session-buffer (save-window-excursion
+			                      (run-mozilla nil)
+			                      (rename-buffer session)
+			                      (current-buffer))))
+      (if (org-babel-comint-buffer-livep session-buffer)
+	        (progn (sit-for .25) session-buffer)
+	      (sit-for .5)
+	      (org-babel-js-initiate-session session))))
+   ((string= "node" org-babel-js-cmd )
+    (error "Session evaluation with node.js is not supported"))
+   (t
+    (error "Sessions are only supported with mozrepl add \":cmd mozrepl\""))))
 
 (provide 'ob-js)
 
-- 
2.16.2

Reply via email to