Browse Source

ob-ruby: clean up the session code some more and work around an I/O sync problem in comint

* lisp/ob-ruby.el (org-babel-ruby-evaluate): Clean up the session code
  and remove a superfluous `butlast'.  Work around a problem in comint
  where the first prompt in a session may be printed after the
  evaluation has already started, thus producing a spurious line in
  the output.

* testing/lisp/test-ob-ruby.el (test-ob-ruby/session-output-1,
  test-ob-ruby/session-output-2 test-ob-ruby/session-output-3): Test
  correct transfer of interpreter state across several session
  invocations.
Achim Gratz 10 years ago
parent
commit
7585fe449b
2 changed files with 59 additions and 18 deletions
  1. 26 17
      lisp/ob-ruby.el
  2. 33 1
      testing/lisp/test-ob-ruby.el

+ 26 - 17
lisp/ob-ruby.el

@@ -209,23 +209,32 @@ return the value of the last statement in BODY, as elisp."
     ;; comint session evaluation
     (case result-type
       (output
-       (mapconcat
-	#'identity
-	(butlast
-	 (split-string
-	  (mapconcat
-	   #'org-babel-trim
-	   (butlast
-	    (org-babel-comint-with-output
-		(buffer org-babel-ruby-eoe-indicator t body)
-	      (mapc
-	       (lambda (line)
-		 (insert (org-babel-chomp line)) (comint-send-input nil t))
-	       (list "conf.echo=false;_org_prompt_mode=conf.prompt_mode;conf.prompt_mode=:NULL"
-		     body
-		     "conf.prompt_mode=_org_prompt_mode;conf.echo=true" org-babel-ruby-eoe-indicator))
-	      ) 2)
-	   "\n") "[\r\n]")) "\n"))
+       (let ((eoe-string (format "puts \"%s\"" org-babel-ruby-eoe-indicator)))
+	 ;; Force the session to be ready before the actual session
+	 ;; code is run.  There is some problem in comint that will
+	 ;; sometimes show the prompt after the the input has already
+	 ;; been inserted and that throws off the extraction of the
+	 ;; result for Babel.
+	 (org-babel-comint-with-output
+	     (buffer org-babel-ruby-eoe-indicator t eoe-string)
+	   (insert eoe-string) (comint-send-input nil t))
+	 ;; Now we can start the evaluation.
+	 (mapconcat
+	  #'identity
+	  (butlast
+	   (split-string
+	    (mapconcat
+	     #'org-babel-trim
+	     (org-babel-comint-with-output
+		 (buffer org-babel-ruby-eoe-indicator t body)
+	       (mapc
+		(lambda (line)
+		  (insert (org-babel-chomp line)) (comint-send-input nil t))
+		(list "conf.echo=false;_org_prompt_mode=conf.prompt_mode;conf.prompt_mode=:NULL"
+		      body
+		      "conf.prompt_mode=_org_prompt_mode;conf.echo=true"
+		      eoe-string)))
+	     "\n") "[\r\n]") 4) "\n")))
       (value
        (let* ((tmp-file (org-babel-temp-file "ruby-"))
 	      (ppp (or (member "code" result-params)

+ 33 - 1
testing/lisp/test-ob-ruby.el

@@ -21,7 +21,7 @@
 (unless (featurep 'ob-ruby)
   (signal 'missing-test-dependency "Support for Ruby code blocks"))
 
-(ert-deftest test-ob-ruby/session-output ()
+(ert-deftest test-ob-ruby/session-output-1 ()
     (should (equal (org-test-with-temp-text "#+begin_src ruby :session :results output
 s = \"1\"
 s = \"2\"
@@ -41,6 +41,38 @@ puts s
 #+RESULTS:
 : 3
 
+")))
+(ert-deftest test-ob-ruby/session-output-2 ()
+    (should (equal (org-test-with-temp-text "#+begin_src ruby :session :results output
+s = \"5\"
+puts s
+#+end_src"
+  (org-ctrl-c-ctrl-c)
+  (substring-no-properties
+   (buffer-string)))
+		   "#+begin_src ruby :session :results output
+s = \"5\"
+puts s
+#+end_src
+
+#+RESULTS:
+: 5
+
+")))
+(ert-deftest test-ob-ruby/session-output-3 ()
+    (should (equal (org-test-with-temp-text "#+begin_src ruby :session :results output
+puts s
+#+end_src"
+  (org-ctrl-c-ctrl-c)
+  (substring-no-properties
+   (buffer-string)))
+		   "#+begin_src ruby :session :results output
+puts s
+#+end_src
+
+#+RESULTS:
+: 5
+
 ")))
 
 (provide 'test-ob-ruby)