Browse Source

`org-babel-comint-with-output' is now robust to errors

Eric Schulte 16 years ago
parent
commit
391f677fc7
2 changed files with 39 additions and 13 deletions
  1. 19 12
      lisp/org-babel-comint.el
  2. 20 1
      org-babel.org

+ 19 - 12
lisp/org-babel-comint.el

@@ -54,24 +54,31 @@ body inside the protection of `save-window-excursion' and
 
 (defmacro org-babel-comint-with-output (buffer eoe-indicator remove-echo &rest body)
   "Evaluate BODY in BUFFER, wait until EOE-INDICATOR appears in
-output, then return all process output."
+output, then return all process output.  This ensures that the
+filter is removed in case of an error or user `keyboard-quit'
+during execution of body."
   (declare (indent 3))
   `(org-babel-comint-in-buffer buffer
      (let ((string-buffer ""))
        (flet ((my-filt (text) (setq string-buffer (concat string-buffer text))))
          ;; setup filter
          (add-hook 'comint-output-filter-functions 'my-filt)
-         ;; pass FULL-BODY to process
-         (goto-char (process-mark (get-buffer-process (current-buffer))))
-         (progn ,@body)
-         ;; wait for end-of-evaluation indicator
-         (while (progn
-                  (goto-char comint-last-input-end)
-                  (not (save-excursion (and (re-search-forward comint-prompt-regexp nil t)
-                                            (re-search-forward (regexp-quote ,eoe-indicator) nil t)))))
-           (accept-process-output (get-buffer-process (current-buffer))))
-         ;; remove filter
-         (remove-hook 'comint-output-filter-functions 'my-filt))
+         (unwind-protect
+             (progn
+               ;; pass FULL-BODY to process
+               (goto-char (process-mark (get-buffer-process (current-buffer))))
+               ,@body
+               ;; wait for end-of-evaluation indicator
+               (while (progn
+                        (goto-char comint-last-input-end)
+                        (not (save-excursion (and (re-search-forward comint-prompt-regexp nil t)
+                                                  (re-search-forward (regexp-quote ,eoe-indicator) nil t)))))
+                 (accept-process-output (get-buffer-process (current-buffer)))
+                 ;; ;; thought this would allow async background running, but I was wrong...
+                 ;; (run-with-timer .5 .5 'accept-process-output (get-buffer-process (current-buffer)))
+                 ))
+           ;; remove filter
+           (remove-hook 'comint-output-filter-functions 'my-filt)))
        ;; remove echo'd FULL-BODY from input
        (if (and ,remove-echo (string-match (replace-regexp-in-string "\n" "\r\n" (regexp-quote ,full-body)) string-buffer))
            (setq raw (substring string-buffer (match-end 0))))

+ 20 - 1
org-babel.org

@@ -1256,7 +1256,26 @@ to the command if BUFF is not given.)
        writing the results to a table
     3) The table is read using =org-table-import=
 
-** DEFERRED Rework Interaction with Running Processes [0/3]
+** DEFERRED Rework Interaction with Running Processes [2/5]
+*** DONE robust to errors interrupting execution
+
+#+srcname: long-runner-ruby
+#+begin_src ruby :results silent
+  sleep(10)
+  :patton_is_an_grumpy
+#+end_src
+
+*** DEFERRED use =C-g= keyboard-quit to push processing into the background
+This may be possible using the `run-with-timer' command.
+
+I have no idea how this could work...
+
+#+srcname: long-runner-ruby
+#+begin_src ruby :results silent
+  sleep(10)
+  :patton_is_an_grumpy
+#+end_src
+
 *** TODO ability to select which of multiple sessions is being used
     Increasingly it is looking like we're going to want to run all
     source code blocks in comint buffer (sessions).  Which will have